<?php

declare(strict_types=1);

require __DIR__ . '/../bootstrap.php';

use Pesisportaali\Core\Response;
use Pesisportaali\Services\PesisApi;
use Pesisportaali\Services\StandingsService;

header('Access-Control-Allow-Origin: https://mailajuniorit.fi');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'OPTIONS') {
    http_response_code(204);
    exit;
}

function pp_team_name(array $team): string
{
    return trim((string)(
        $team['name']
        ?? $team['shorthand']
        ?? ''
    ));
}

function pp_date_range(
    DateTimeImmutable $start,
    DateTimeImmutable $end
): array {
    $dates = [];

    for ($date = $start; $date <= $end; $date = $date->modify('+1 day')) {
        $dates[] = $date->format('Y-m-d');
    }

    return $dates;
}

function pp_group_is_cross(string $name): bool
{
    $name = mb_strtolower($name, 'UTF-8');

    return
        str_contains($name, 'ristikk') ||
        str_contains($name, 'ristiin');
}

function pp_choose_primary_group(
    array $teamGroups,
    int $fallbackGroupId
): int {
    $best = null;

    foreach ($teamGroups as $group) {
        if (pp_group_is_cross((string)($group['name'] ?? ''))) {
            continue;
        }

        if (
            $best === null ||
            (int)$group['played'] > (int)$best['played'] ||
            (
                (int)$group['played'] === (int)$best['played'] &&
                (int)$group['matches'] > (int)$best['matches']
            )
        ) {
            $best = $group;
        }
    }

    return $best !== null
        ? (int)$best['id']
        : $fallbackGroupId;
}

if (!$pdo instanceof PDO) {
    Response::json([
        'success' => false,
        'error' => 'Tietokantayhteys puuttuu.',
    ], 500);
}

$slug = trim((string)($_GET['joukkue'] ?? ''));
$referenceMatchId = (int)($_GET['ottelu'] ?? 0);
$force = ($_GET['force'] ?? '') === '1';

if ($slug === '') {
    Response::json([
        'success' => false,
        'error' => 'Anna joukkue-parametri.',
    ], 400);
}

if ($referenceMatchId <= 0) {
    Response::json([
        'success' => false,
        'error' => 'Anna testissä ottelu-parametri.',
    ], 400);
}

$stmt = $pdo->prepare(
    "SELECT
        t.*,
        c.slug AS club_slug,
        c.name AS club_name,
        c.primary_color
     FROM pp_teams t
     INNER JOIN pp_clubs c
        ON c.id = t.club_id
     WHERE t.slug = ?
       AND t.active = 1
     LIMIT 1"
);

$stmt->execute([$slug]);
$team = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$team) {
    Response::json([
        'success' => false,
        'error' => 'Joukkuetta ei löytynyt.',
    ], 404);
}

$cacheKey =
    'sarjataulukko_' .
    $slug .
    '_' .
    $referenceMatchId;

if (!$force) {
    $stmt = $pdo->prepare(
        "SELECT payload
         FROM pp_api_cache
         WHERE cache_key = ?
           AND expires_at > NOW()
         LIMIT 1"
    );

    $stmt->execute([$cacheKey]);
    $cachedPayload = $stmt->fetchColumn();

    if ($cachedPayload) {
        $cached = json_decode((string)$cachedPayload, true);

        if (is_array($cached)) {
            $cached['cache']['hit'] = true;
            Response::json($cached);
        }
    }
}

try {
    $api = new PesisApi();
    $standingsService = new StandingsService();

    $referenceMatch = $api->get(
        'match?id=' . $referenceMatchId
    );

    $seasonSeriesId = (int)(
        $referenceMatch['series']['id']
        ?? $team['season_series_id']
        ?? 0
    );

    $referenceGroupId = (int)(
        $referenceMatch['series']['groupId']
        ?? 0
    );

    $teamId = (int)$team['pesis_team_id'];

    if ($seasonSeriesId <= 0 || $referenceGroupId <= 0) {
        throw new RuntimeException(
            'Sarjan tai ryhmän tunnistaminen epäonnistui.'
        );
    }

    $referenceDate = new DateTimeImmutable(
        (string)($referenceMatch['date'] ?? 'now')
    );

    $startDate = $referenceDate->modify('-120 days');
    $endDate = $referenceDate->modify('+120 days');

    $groups = [];
    $teamGroups = [];

    foreach (pp_date_range($startDate, $endDate) as $date) {
        $dailyData = $api->get(
            'matches-list?date=' . urlencode($date)
        );

        foreach ($dailyData as $seriesBlock) {
            if (!is_array($seriesBlock)) {
                continue;
            }

            $blockSeriesId = (int)(
                $seriesBlock['seasonSeries']['id']
                ?? 0
            );

            if ($blockSeriesId !== $seasonSeriesId) {
                continue;
            }

            foreach (($seriesBlock['groups'] ?? []) as $groupBlock) {
                $groupId = (int)(
                    $groupBlock['group']['id']
                    ?? 0
                );

                if ($groupId <= 0) {
                    continue;
                }

                $groupName = (string)(
                    $groupBlock['group']['name']
                    ?? ''
                );

                if (!isset($groups[$groupId])) {
                    $groups[$groupId] = [
                        'id' => $groupId,
                        'name' => $groupName,
                        'settings' =>
                            $groupBlock['group']['settings']
                            ?? [],
                        'matches' => [],
                    ];
                }

                foreach (($groupBlock['matches'] ?? []) as $match) {
                    $matchId = (int)($match['id'] ?? 0);

                    if ($matchId <= 0) {
                        continue;
                    }

                    $groups[$groupId]['matches'][$matchId] = $match;

                    $homeId = (int)($match['home']['id'] ?? 0);
                    $awayId = (int)($match['away']['id'] ?? 0);

                    if ($homeId !== $teamId && $awayId !== $teamId) {
                        continue;
                    }

                    if (!isset($teamGroups[$groupId])) {
                        $teamGroups[$groupId] = [
                            'id' => $groupId,
                            'name' => $groupName,
                            'matches' => 0,
                            'played' => 0,
                        ];
                    }

                    $teamGroups[$groupId]['matches']++;

                    if (!empty($match['result'])) {
                        $teamGroups[$groupId]['played']++;
                    }
                }
            }
        }
    }

    $primaryGroupId = pp_choose_primary_group(
        $teamGroups,
        (int)($team['series_group_id'] ?? $referenceGroupId)
    );

    $relatedGroupIds = [];

    foreach ($groups as $groupId => $group) {
        $settings = is_array($group['settings'] ?? null)
            ? $group['settings']
            : [];

        $sources = array_map(
            'intval',
            $settings['union_groups_as_source'] ?? []
        );

        if (in_array($primaryGroupId, $sources, true)) {
            $relatedGroupIds[] = (int)$groupId;
        }
    }

    $groupMatches = array_values(
        $groups[$primaryGroupId]['matches'] ?? []
    );

    $relatedMatchesById = [];

    foreach ($relatedGroupIds as $groupId) {
        foreach (($groups[$groupId]['matches'] ?? []) as $matchId => $match) {
            $relatedMatchesById[(int)$matchId] = $match;
        }
    }

    $relatedMatches = array_values($relatedMatchesById);

    $standings = $standingsService->build(
        $groupMatches,
        $relatedMatches
    );

    $response = [
        'success' => true,
        'team' => [
            'slug' => $team['slug'],
            'id' => $teamId,
            'name' => $team['name'],
            'color' => $team['primary_color'],
        ],
        'series' => [
            'id' => $seasonSeriesId,
            'name' =>
                $referenceMatch['series']['custom_name']
                ?? $referenceMatch['series']['name']
                ?? $team['series_name'],
            'season' => (int)$team['season'],
        ],
        'group' => [
            'id' => $primaryGroupId,
            'name' => $groups[$primaryGroupId]['name'] ?? '',
        ],
        'related_groups' => array_map(
            static fn(int $groupId): array => [
                'id' => $groupId,
                'name' => $groups[$groupId]['name'] ?? '',
            ],
            $relatedGroupIds
        ),
        'standings' => $standings,
        'debug' => [
            'reference_match_id' => $referenceMatchId,
            'range_start' => $startDate->format('Y-m-d'),
            'range_end' => $endDate->format('Y-m-d'),
            'group_matches' => count($groupMatches),
            'related_matches' => count($relatedMatches),
        ],
        'cache' => [
            'hit' => false,
            'ttl' => 3600,
        ],
    ];

    $stmt = $pdo->prepare(
        "REPLACE INTO pp_api_cache
         (cache_key, payload, expires_at)
         VALUES (
             ?,
             ?,
             DATE_ADD(NOW(), INTERVAL 3600 SECOND)
         )"
    );

    $stmt->execute([
        $cacheKey,
        json_encode(
            $response,
            JSON_UNESCAPED_UNICODE |
            JSON_UNESCAPED_SLASHES
        ),
    ]);

    Response::json($response);

} catch (Throwable $error) {
    Response::json([
        'success' => false,
        'error' => $error->getMessage(),
    ], 500);
}
