<?php

use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Module\Helpdesk\HelpdeskAuthorizationPolicy;
use MintyPHP\Module\Helpdesk\Service\DebitorCacheControl;
use MintyPHP\Module\Helpdesk\Service\DebitorDetailService;
use MintyPHP\Module\Helpdesk\Service\HelpdeskSettingsGateway;
use MintyPHP\Module\Helpdesk\Service\SystemRecommendationEngine;
use MintyPHP\Router;
use MintyPHP\Support\Guard;

Guard::requireLogin();
Guard::requireAbilityOrForbidden(HelpdeskAuthorizationPolicy::ABILITY_ACCESS);

gridRequireGetRequest();

$request = requestInput();
$customerNo = trim((string) $request->query('customerNo', ''));
$customerName = trim((string) $request->query('customerName', ''));
$refreshRequested = DebitorCacheControl::parseRefreshFlag($request->query('refresh', ''));

if ($customerNo === '' || $customerName === '') {
    http_response_code(400);
    Router::json(['ok' => false, 'error' => 'Missing parameters']);

    return;
}

$sessionStore = app(SessionStoreInterface::class);
$session = $sessionStore->all();
$tenantScope = DebitorCacheControl::resolveTenantScope($session);
if ($refreshRequested) {
    DebitorCacheControl::invalidateDebitorCaches($sessionStore, $tenantScope, $customerNo, true);
}

$cacheKey = DebitorCacheControl::ticketsKey($tenantScope, $customerNo);
$cacheTtl = DebitorCacheControl::TTL_STANDARD_SECONDS;
$cached = $sessionStore->get($cacheKey);
$tickets = null;
$sourceCacheUsed = false;

if (!$refreshRequested && is_array($cached) && isset($cached['fetched_at']) && (time() - (int) $cached['fetched_at']) < $cacheTtl) {
    $tickets = $cached['tickets'] ?? [];
    $sourceCacheUsed = true;
}

if ($tickets === null) {
    $service = app(DebitorDetailService::class);
    $ticketsResult = $service->loadTickets($customerNo, $customerName);

    if (!($ticketsResult['ok'] ?? false)) {
        Router::json([
            'ok' => false,
            'error' => (string) ($ticketsResult['error'] ?? 'Failed to load tickets'),
        ]);

        return;
    }

    $tickets = $ticketsResult['tickets'] ?? [];
    if (!is_array($tickets)) {
        $tickets = [];
    }

    $sessionStore->set($cacheKey, [
        'tickets' => $tickets,
        'fetched_at' => time(),
    ]);
}

if (!is_array($tickets)) {
    $tickets = [];
}

$service = app(DebitorDetailService::class);
$escalationCacheKey = DebitorCacheControl::escalationKey($tenantScope, $customerNo);
$escalationCached = $sessionStore->get($escalationCacheKey);
$escalationSourceCacheUsed = false;
$escalationPayload = null;

if (!$refreshRequested && is_array($escalationCached) && isset($escalationCached['fetched_at']) && (time() - (int) $escalationCached['fetched_at']) < $cacheTtl) {
    $escalationPayload = [
        'ok' => (bool) ($escalationCached['ok'] ?? false),
        'overdue_count' => (int) ($escalationCached['overdue_count'] ?? 0),
        'entries' => is_array($escalationCached['entries'] ?? null) ? $escalationCached['entries'] : [],
        'matches' => is_array($escalationCached['matches'] ?? null) ? $escalationCached['matches'] : [],
        'tickets_considered' => (int) ($escalationCached['tickets_considered'] ?? 0),
        'tickets_matched' => (int) ($escalationCached['tickets_matched'] ?? 0),
        'definitions_count' => (int) ($escalationCached['definitions_count'] ?? 0),
        'error' => (string) ($escalationCached['error'] ?? ''),
    ];
    $escalationSourceCacheUsed = true;
}

if ($escalationPayload === null) {
    $escalationResult = $service->loadEscalationHealth($customerNo, $tickets);
    $escalationPayload = $escalationResult;

    $sessionStore->set($escalationCacheKey, [
        'ok' => (bool) ($escalationResult['ok'] ?? false),
        'overdue_count' => (int) ($escalationResult['overdue_count'] ?? 0),
        'entries' => is_array($escalationResult['entries'] ?? null) ? $escalationResult['entries'] : [],
        'matches' => is_array($escalationResult['matches'] ?? null) ? $escalationResult['matches'] : [],
        'tickets_considered' => (int) ($escalationResult['tickets_considered'] ?? 0),
        'tickets_matched' => (int) ($escalationResult['tickets_matched'] ?? 0),
        'definitions_count' => (int) ($escalationResult['definitions_count'] ?? 0),
        'error' => (string) ($escalationResult['error'] ?? ''),
        'fetched_at' => time(),
    ]);
}

$dashboard = DebitorDetailService::buildSupportDashboard(
    $tickets,
    48,
    (($escalationPayload['ok'] ?? false) ? $escalationPayload : null)
);
$settingsGateway = app(HelpdeskSettingsGateway::class);
$recommendationConfigEnvelope = $settingsGateway->getSystemRecommendationsConfigEnvelope();
$recommendationConfig = is_array($recommendationConfigEnvelope['config'] ?? null)
    ? $recommendationConfigEnvelope['config']
    : [];
$recommendationEngine = app(SystemRecommendationEngine::class);
$recommendationResult = $recommendationEngine->buildRecommendations(
    $tickets,
    (($escalationPayload['ok'] ?? false) ? $escalationPayload : null),
    $recommendationConfig
);
$recommendations = is_array($recommendationResult['recommendations'] ?? null)
    ? $recommendationResult['recommendations']
    : [];
$recommendationsMeta = is_array($recommendationResult['meta'] ?? null)
    ? $recommendationResult['meta']
    : [];
$meta = $dashboard['meta'];
$meta['source_cache_used'] = $sourceCacheUsed;
$meta['escalation_source_cache_used'] = $escalationSourceCacheUsed;
$meta['cache_used'] = ($sourceCacheUsed || $escalationSourceCacheUsed);
$meta['cache_bypassed'] = $refreshRequested;
$meta['cache_refreshed'] = $refreshRequested;

$contractsCacheKey = DebitorCacheControl::contractsKey($tenantScope, $customerNo);
$contractsCached = $sessionStore->get($contractsCacheKey);
$contractsSourceCacheUsed = false;
$contractsPayload = null;

if (!$refreshRequested && is_array($contractsCached) && isset($contractsCached['fetched_at']) && (time() - (int) $contractsCached['fetched_at']) < $cacheTtl) {
    $contractsPayload = [
        'ok' => true,
        'entries' => is_array($contractsCached['entries'] ?? null) ? $contractsCached['entries'] : [],
        'summary' => is_array($contractsCached['summary'] ?? null) ? $contractsCached['summary'] : [
            'total_contracts' => 0,
            'active_contracts' => 0,
            'product_types' => [],
        ],
    ];
    $contractsSourceCacheUsed = true;
}

if ($contractsPayload === null) {
    $contractsResult = $service->loadContracts($customerNo);
    if ($contractsResult['ok'] ?? false) {
        $entries = is_array($contractsResult['entries'] ?? null) ? $contractsResult['entries'] : [];
        $summary = is_array($contractsResult['summary'] ?? null) ? $contractsResult['summary'] : [
            'total_contracts' => 0,
            'active_contracts' => 0,
            'product_types' => [],
        ];

        $contractsPayload = [
            'ok' => true,
            'entries' => $entries,
            'summary' => $summary,
        ];

        $sessionStore->set($contractsCacheKey, [
            'entries' => $entries,
            'summary' => $summary,
            'fetched_at' => time(),
        ]);
    } else {
        $contractsPayload = [
            'ok' => false,
            'entries' => [],
            'summary' => [
                'total_contracts' => 0,
                'active_contracts' => 0,
                'product_types' => [],
            ],
            'error' => (string) ($contractsResult['error'] ?? 'Failed to load contracts'),
        ];
    }
}

$meta['cache_used'] = ($sourceCacheUsed || $escalationSourceCacheUsed || $contractsSourceCacheUsed);

Router::json([
    'ok' => true,
    'health' => $dashboard['health'],
    'recommendations' => $recommendations,
    'recommendations_meta' => [
        'config_source' => (string) ($recommendationConfigEnvelope['source'] ?? 'default'),
        'applied_rules' => is_array($recommendationsMeta['applied_rules'] ?? null) ? $recommendationsMeta['applied_rules'] : [],
        'max_items' => (int) ($recommendationsMeta['max_items'] ?? (($recommendationConfig['max_items'] ?? 5))),
        'escalation_data_available' => (bool) ($recommendationsMeta['escalation_data_available'] ?? false),
        'cache_used' => ($sourceCacheUsed || $escalationSourceCacheUsed || $contractsSourceCacheUsed),
        'cache_bypassed' => $refreshRequested,
        'cache_refreshed' => $refreshRequested,
    ],
    'actions' => $recommendations,
    'meta' => $meta,
    'contracts' => $contractsPayload['entries'],
    'contracts_summary' => $contractsPayload['summary'],
    'contracts_meta' => [
        'available' => $contractsPayload['ok'],
        'source_cache_used' => $contractsSourceCacheUsed,
        'cache_used' => $contractsSourceCacheUsed,
        'cache_bypassed' => $refreshRequested,
        'cache_refreshed' => $refreshRequested,
        'error' => (string) ($contractsPayload['error'] ?? ''),
    ],
    'escalation_entries' => is_array($escalationPayload['entries'] ?? null) ? $escalationPayload['entries'] : [],
    'escalation_meta' => [
        'available' => (bool) ($escalationPayload['ok'] ?? false),
        'source_cache_used' => $escalationSourceCacheUsed,
        'cache_used' => $escalationSourceCacheUsed,
        'cache_bypassed' => $refreshRequested,
        'cache_refreshed' => $refreshRequested,
        'error' => (string) ($escalationPayload['error'] ?? ''),
        'tickets_considered' => (int) ($escalationPayload['tickets_considered'] ?? 0),
        'tickets_matched' => (int) ($escalationPayload['tickets_matched'] ?? 0),
        'definitions_count' => (int) ($escalationPayload['definitions_count'] ?? 0),
    ],
]);
