<?php

namespace Espo\Modules\SmartAssistant\Services;

use Espo\ORM\EntityManager;
use Espo\Core\Utils\Log;

class CaseMemoryContextProvider
{
    private const MAX_CONTEXT_CHARS = 4000;

    private EntityManager $entityManager;
    private Log $log;

    public function __construct(EntityManager $entityManager, Log $log)
    {
        $this->entityManager = $entityManager;
        $this->log = $log;
    }

    public function getContextForCase(string $caseId): array
    {
        $entries = $this->entityManager->getRDBRepository('CaseMemory')
            ->where(['caseId' => $caseId, 'isArchived' => false, 'deleted' => false])
            ->order([['isPinned', 'DESC'], ['importance', 'ASC'], ['createdAt', 'DESC']])
            ->find();

        $grouped = [];
        $totalChars = 0;
        $totalEntries = 0;
        $pinnedCount = 0;
        $criticalCount = 0;

        // Priority order for importance
        $importancePriority = ['critical' => 0, 'high' => 1, 'normal' => 2, 'low' => 3];

        // Sort: pinned first, then by importance, then by date
        $sorted = [];
        foreach ($entries as $entry) {
            $sorted[] = $entry;
        }

        usort($sorted, function ($a, $b) use ($importancePriority) {
            if ($a->get('isPinned') !== $b->get('isPinned')) {
                return $b->get('isPinned') <=> $a->get('isPinned');
            }
            $aP = $importancePriority[$a->get('importance')] ?? 4;
            $bP = $importancePriority[$b->get('importance')] ?? 4;
            if ($aP !== $bP) return $aP <=> $bP;
            return strcmp($b->get('createdAt') ?? '', $a->get('createdAt') ?? '');
        });

        foreach ($sorted as $entry) {
            $content = $entry->get('content') ?? '';
            $contentLen = mb_strlen($content);

            // Check budget
            if ($totalChars + $contentLen > self::MAX_CONTEXT_CHARS && !$entry->get('isPinned') && $entry->get('importance') !== 'critical') {
                continue;
            }

            $cat = $entry->get('category');
            if (!isset($grouped[$cat])) $grouped[$cat] = [];

            $grouped[$cat][] = [
                'content' => $content,
                'importance' => $entry->get('importance'),
                'pinned' => $entry->get('isPinned'),
                'createdAt' => $entry->get('createdAt'),
            ];

            $totalChars += $contentLen;
            $totalEntries++;

            if ($entry->get('isPinned')) $pinnedCount++;
            if ($entry->get('importance') === 'critical') $criticalCount++;
        }

        $grouped['_summary'] = [
            'totalEntries' => $totalEntries,
            'pinnedCount' => $pinnedCount,
            'criticalCount' => $criticalCount,
        ];

        return $grouped;
    }
}
