<?php

namespace App\Libraries;

use App\Models\FootballLeagueModel;
use App\Models\FootballSettingModel;

class FootballFixturesDailySync
{
    protected FootballLeagueModel $leagueModel;
    protected FootballSettingModel $settingModel;

    public function __construct()
    {
        $this->leagueModel = new FootballLeagueModel();
        $this->settingModel = new FootballSettingModel();
    }

    /**
     * Refresh fixture cache for every league in DB (intended for midnight cron / admin).
     *
     * @return array{leagues: int, fixtures: int, errors: list<string>}
     */
    public function syncAll(int $daysAhead = 14): array
    {
        $tz = new \DateTimeZone($this->settingModel->timezone());
        $fromDt = new \DateTime('today', $tz);
        $toDt = (clone $fromDt)->modify('+' . $daysAhead . ' days');

        $from = $fromDt->format('Y-m-d');
        $to = $toDt->format('Y-m-d');

        $leagueSync = new FootballLeagueSync();
        $leagues = $this->leagueModel->select('id, name, country_name')->findAll();

        $fixtureTotal = 0;
        $leagueCount = 0;
        $errors = [];

        foreach ($leagues as $league) {
            try {
                $result = $leagueSync->syncLeagueData((int) $league['id'], $from, $to, true);
                $fixtureTotal += (int) ($result['fixtures_synced'] ?? 0);
                $leagueCount++;
            } catch (\Throwable $e) {
                $errors[] = ($league['name'] ?? 'League') . ': ' . $e->getMessage();
                log_message('warning', 'Fixture daily sync failed for league {id}: {msg}', [
                    'id' => $league['id'],
                    'msg' => $e->getMessage(),
                ]);
            }
        }

        $leagueSync->pruneOldFixtures(30, $daysAhead + 7);

        $this->settingModel->updateSettings([
            'last_fixtures_sync_at' => date('Y-m-d H:i:s'),
            'fixtures_cache_from' => $from,
            'fixtures_cache_to' => $to,
        ]);

        return [
            'leagues' => $leagueCount,
            'fixtures' => $fixtureTotal,
            'from' => $from,
            'to' => $to,
            'errors' => $errors,
        ];
    }

    /**
     * Sync a slice of leagues (for web UI — avoids gateway timeouts).
     *
     * @return array{offset: int, limit: int, total: int, processed: int, fixtures: int, done: bool, from: string, to: string, errors: list<string>}
     */
    public function syncBatch(int $offset, int $limit = 20, int $daysAhead = 14): array
    {
        $tz = new \DateTimeZone($this->settingModel->timezone());
        $fromDt = new \DateTime('today', $tz);
        $toDt = (clone $fromDt)->modify('+' . $daysAhead . ' days');
        $from = $fromDt->format('Y-m-d');
        $to = $toDt->format('Y-m-d');

        $total = $this->leagueModel->countAllResults();
        $leagues = $this->leagueModel->orderBy('id', 'ASC')->findAll($limit, $offset);

        $leagueSync = new FootballLeagueSync();
        $fixtureTotal = 0;
        $errors = [];

        foreach ($leagues as $league) {
            try {
                $result = $leagueSync->syncLeagueData((int) $league['id'], $from, $to, true);
                $fixtureTotal += (int) ($result['fixtures_synced'] ?? 0);
            } catch (\Throwable $e) {
                $errors[] = ($league['name'] ?? 'League') . ': ' . $e->getMessage();
            }
        }

        $processed = count($leagues);
        $nextOffset = $offset + $processed;
        $done = $nextOffset >= $total || $processed === 0;

        if ($done) {
            $leagueSync->pruneOldFixtures(30, $daysAhead + 7);
            $this->settingModel->updateSettings([
                'last_fixtures_sync_at' => date('Y-m-d H:i:s'),
                'fixtures_cache_from' => $from,
                'fixtures_cache_to' => $to,
            ]);
        }

        return [
            'offset' => $offset,
            'limit' => $limit,
            'total' => $total,
            'processed' => $processed,
            'next_offset' => $nextOffset,
            'fixtures' => $fixtureTotal,
            'done' => $done,
            'from' => $from,
            'to' => $to,
            'errors' => $errors,
        ];
    }

    public function cacheWindow(): array
    {
        $settings = $this->settingModel->getSettings();
        $tz = new \DateTimeZone($this->settingModel->timezone());
        $from = $settings['fixtures_cache_from'] ?? (new \DateTime('today', $tz))->format('Y-m-d');
        $to = $settings['fixtures_cache_to'] ?? (new \DateTime('today', $tz))->modify('+14 days')->format('Y-m-d');

        return ['from' => $from, 'to' => $to];
    }
}
