<?php

namespace App\Controllers;

use App\Libraries\FootballFixturesDailySync;
use App\Libraries\FootballReferenceSync;
use App\Models\FootballCountryModel;
use App\Models\FootballFixtureModel;
use App\Models\FootballLeagueModel;
use App\Models\FootballSettingModel;
use CodeIgniter\HTTP\ResponseInterface;

class FootballCatalog extends BaseController
{
    protected FootballCountryModel $countryModel;
    protected FootballLeagueModel $leagueModel;
    protected FootballFixtureModel $fixtureModel;
    protected FootballSettingModel $settingModel;

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

    public function countries(): ResponseInterface
    {
        $q = $this->request->getGet('q');
        $rows = $this->countryModel->search($q);

        $data = array_map(static function ($row) {
            return [
                'id' => (int) $row['id'],
                'name' => $row['api_name'],
                'code' => $row['code'],
                'flag' => $row['flag_url'],
            ];
        }, $rows);

        if ($data === []) {
            return $this->respondJson([
                'success' => true,
                'data' => [],
                'message' => 'No countries in catalog. Run football:sync-reference or refresh from Admin → Football catalog.',
            ]);
        }

        return $this->respondJson(['success' => true, 'data' => $data]);
    }

    public function leagues(): ResponseInterface
    {
        $country = trim((string) $this->request->getGet('country'));
        if ($country === '') {
            return $this->respondJson(['success' => false, 'message' => 'country is required'], 400);
        }

        $search = $this->request->getGet('q');
        $rows = $this->leagueModel->forCountry($country, $search);

        $data = array_map(static function ($row) {
            return [
                'id' => (int) $row['id'],
                'api_league_id' => (int) $row['api_league_id'],
                'name' => $row['name'],
                'country' => $row['country_name'],
                'type' => $row['type'],
                'logo' => $row['logo_url'],
            ];
        }, $rows);

        return $this->respondJson(['success' => true, 'data' => $data]);
    }

    /**
     * Fixtures from DB cache only (no API calls). Populated by daily cron or admin refresh.
     */
    public function fixtures(): ResponseInterface
    {
        $leagueId = (int) $this->request->getGet('league_id');
        if ($leagueId <= 0) {
            return $this->respondJson(['success' => false, 'message' => 'league_id is required'], 400);
        }

        $league = $this->leagueModel->find($leagueId);
        if (!$league) {
            return $this->respondJson(['success' => false, 'message' => 'League not found'], 404);
        }

        $cache = (new FootballFixturesDailySync())->cacheWindow();
        $from = $this->request->getGet('from') ?: $cache['from'];
        $to = $this->request->getGet('to') ?: $cache['to'];
        $season = $this->settingModel->currentSeason();

        $search = $this->request->getGet('q');
        $rows = $this->fixtureModel->forLeagueInRange($leagueId, $season, $from, $to, $search);
        $settings = $this->settingModel->getSettings();

        $data = array_map(static function ($row) {
            return [
                'id' => (int) $row['id'],
                'fixture_id' => (int) $row['api_fixture_id'],
                'team1' => $row['home_name'] ?? '',
                'team2' => $row['away_name'] ?? '',
                'team1_logo' => $row['home_logo'] ?? null,
                'team2_logo' => $row['away_logo'] ?? null,
                'league' => trim(($row['league_name'] ?? '') . ' - ' . ($row['country_name'] ?? ''), ' -'),
                'league_logo' => $row['league_logo'] ?? null,
                'kickoff' => $row['kickoff_local'],
                'status' => $row['status_short'],
                'round' => $row['round'],
            ];
        }, $rows);

        $message = null;
        if ($data === []) {
            $message = 'No cached fixtures for this league. Ask admin to run fixture cache refresh, or wait for the midnight sync.';
        }

        return $this->respondJson([
            'success' => true,
            'timezone' => $settings['timezone'] ?? 'Africa/Nairobi',
            'cache_from' => $from,
            'cache_to' => $to,
            'last_fixtures_sync_at' => $settings['last_fixtures_sync_at'] ?? null,
            'message' => $message,
            'data' => $data,
        ]);
    }

    public function syncReference(): ResponseInterface
    {
        @set_time_limit(300);
        ini_set('memory_limit', '512M');

        try {
            $result = (new FootballReferenceSync())->syncAll();

            return $this->respondJson([
                'success' => true,
                'countries' => $result['countries'],
                'leagues' => $result['leagues'],
                'warnings' => $result['warnings'],
            ]);
        } catch (\Throwable $e) {
            log_message('error', 'syncReference: {msg}', ['msg' => $e->getMessage()]);

            return $this->respondJson(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    /**
     * Full fixture sync — use CLI/cron only (too slow for one HTTP request).
     */
    public function syncFixturesCache(): ResponseInterface
    {
        return $this->respondJson([
            'success' => false,
            'message' => 'Use batch sync from this page, or run: php spark football:sync-fixtures-daily',
            'use_batch' => true,
        ], 400);
    }

    /**
     * Sync fixtures for a batch of leagues (web-safe, returns JSON).
     */
    public function syncFixturesBatch(): ResponseInterface
    {
        @set_time_limit(180);
        ini_set('memory_limit', '256M');

        $offset = max(0, (int) $this->request->getGet('offset'));
        $limit = min(50, max(5, (int) ($this->request->getGet('limit') ?: 20)));

        try {
            $result = (new FootballFixturesDailySync())->syncBatch($offset, $limit);

            return $this->respondJson([
                'success' => true,
                'offset' => $result['offset'],
                'next_offset' => $result['next_offset'],
                'total' => $result['total'],
                'processed' => $result['processed'],
                'fixtures' => $result['fixtures'],
                'done' => $result['done'],
                'from' => $result['from'],
                'to' => $result['to'],
                'errors' => array_slice($result['errors'], 0, 5),
            ]);
        } catch (\Throwable $e) {
            log_message('error', 'syncFixturesBatch: {msg}', ['msg' => $e->getMessage()]);

            return $this->respondJson(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    protected function respondJson(array $payload, int $status = 200): ResponseInterface
    {
        return $this->response
            ->setStatusCode($status)
            ->setHeader('Content-Type', 'application/json; charset=UTF-8')
            ->setJSON($payload);
    }
}
