<?php

declare(strict_types=1);

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

use Pesisportaali\Core\Response;

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_error(string $message, int $status = 500, array $extra = []): void
{
    Response::json(array_merge([
        'success' => false,
        'error' => $message,
    ], $extra), $status);
}

function pp_api_get(string $endpoint): array|false
{
    $endpoint = ltrim($endpoint, '/');
    $separator = str_contains($endpoint, '?') ? '&' : '?';

    $url = 'https://api.pesistulokset.fi/api/v1/public/' .
        $endpoint .
        $separator .
        'apikey=' .
        urlencode(PESIS_API_KEY);

    $ch = curl_init();

    $options = [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
        CURLOPT_ENCODING => '',
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2TLS,
        CURLOPT_HTTPHEADER => [
            'Accept: application/json, text/plain, */*',
            'X-API-Key: ' . PESIS_API_KEY,
            'Accept-Language: fi-FI,fi;q=0.9',
            'User-Agent: Mozilla/5.0 Pesisportaali/1.0',
            'Referer: https://www.pesistulokset.fi/',
            'Origin: https://www.pesistulokset.fi',
        ],
    ];

    if (defined('PESIS_OUTGOING_IP') && PESIS_OUTGOING_IP !== '') {
        $options[CURLOPT_INTERFACE] = PESIS_OUTGOING_IP;
    }

    curl_setopt_array($ch, $options);

    $response = curl_exec($ch);
    $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $errno = curl_errno($ch);
    $error = curl_error($ch);

    curl_close($ch);

    if ($errno !== 0 || $status !== 200 || !$response) {
        $GLOBALS['PP_API_ERROR'] = [
            'endpoint' => $endpoint,
            'http_status' => $status,
            'curl_errno' => $errno,
            'curl_error' => $error,
        ];

        return false;
    }

    $data = json_decode((string)$response, true);

    return is_array($data) ? $data : false;
}

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

function pp_team_logo(array $team): string
{
    return (string)($team['logo'] ?? $team['icon'] ?? $team['square'] ?? '');
}

function pp_group_name(array $item): string
{
    return trim((string)(
        $item['group']['name']
        ?? $item['phase']['name']
        ?? ''
    ));
}

function pp_flatten_matches(array $items, string $groupName = ''): array
{
    $matches = [];

    foreach ($items as $item) {
        if (!is_array($item)) {
            continue;
        }

        $currentGroup = pp_group_name($item) ?: $groupName;

        if (!empty($item['matches']) && is_array($item['matches'])) {
            foreach ($item['matches'] as $match) {
                if (!is_array($match)) {
                    continue;
                }

                $match['_group_name'] = $currentGroup;
                $matches[] = $match;
            }
        }

        foreach ($item as $value) {
            if (is_array($value)) {
                $matches = array_merge(
                    $matches,
                    pp_flatten_matches($value, $currentGroup)
                );
            }
        }
    }

    return $matches;
}

function pp_match_status(array $match, array $detail = []): string
{
    if (!empty($match['canceled']) || !empty($detail['canceled'])) {
        return 'canceled';
    }

    if (!empty($match['live']) || !empty($detail['live'])) {
        return 'live';
    }

    if (
        !empty($detail['result']) ||
        !empty($match['result']) ||
        !empty($detail['started'])
    ) {
        return 'finished';
    }

    return 'scheduled';
}

function pp_maps_url(string $address, string $stadiumName): string
{
    $query = trim($address);

    if ($query === '') {
        $query = trim($stadiumName);
    }

    if ($query === '') {
        return '';
    }

    return 'https://www.google.com/maps/search/?api=1&query=' .
        rawurlencode($query);
}

function pp_score_data(array $detail): array
{
    $result = is_array($detail['result'] ?? null)
        ? $detail['result']
        : [];

    $details = is_array($result['details'] ?? null)
        ? $result['details']
        : [];

    $simpleScoreKeeping =
        (bool)($detail['meta']['simple_score_keeping'] ?? false);

    $resultString = trim((string)(
        $result['result_string']
        ?? $result['result_string_periods']
        ?? ''
    ));

    $setsHome = $result['periods_home']
        ?? $details['periods_home']
        ?? null;

    $setsAway = $result['periods_away']
        ?? $details['periods_away']
        ?? null;

    $periods = [];

    $periodFields = [
        [
            'label' => '1. jakso',
            'home' => $result['runs_home_first_period']
                ?? $details['runs_home_first_period']
                ?? null,
            'away' => $result['runs_away_first_period']
                ?? $details['runs_away_first_period']
                ?? null,
        ],
        [
            'label' => '2. jakso',
            'home' => $result['runs_home_second_period']
                ?? $details['runs_home_second_period']
                ?? null,
            'away' => $result['runs_away_second_period']
                ?? $details['runs_away_second_period']
                ?? null,
        ],
        [
            'label' => 'Supervuoro',
            'home' => $result['runs_home_super_inning']
                ?? $details['runs_home_super_inning']
                ?? null,
            'away' => $result['runs_away_super_inning']
                ?? $details['runs_away_super_inning']
                ?? null,
        ],
        [
            'label' => 'Kotiutuslyönnit',
            'home' => $result['runs_home_scoring_contest']
                ?? $details['runs_home_scoring_contest']
                ?? null,
            'away' => $result['runs_away_scoring_contest']
                ?? $details['runs_away_scoring_contest']
                ?? null,
        ],
    ];

    foreach ($periodFields as $period) {
        if ($period['home'] === null || $period['away'] === null) {
            continue;
        }

        $periods[] = [
            'label' => $period['label'],
            'home' => (int)$period['home'],
            'away' => (int)$period['away'],
        ];
    }

    $sets = '';

    if ($setsHome !== null && $setsAway !== null) {
        $sets = (int)$setsHome . '–' . (int)$setsAway;
    } elseif (!$simpleScoreKeeping && $resultString !== '') {
        $sets = $resultString;
    }

    return [
        'simple_score_keeping' => $simpleScoreKeeping,
        'result_string' => $resultString,
        'sets' => $sets,
        'periods' => $periods,
    ];
}

if (!$pdo instanceof PDO) {
    pp_error('Tietokantayhteys ei muodostunut');
}

$clubSlug = trim((string)(
    $_GET['seura']
    ?? $_GET['club']
    ?? 'mailajuniorit'
));

$date = trim((string)($_GET['date'] ?? date('Y-m-d')));
$force = isset($_GET['force']) && $_GET['force'] === '1';

$stmt = $pdo->prepare(
    'SELECT * FROM pp_clubs
     WHERE slug = ?
       AND active = 1
     LIMIT 1'
);
$stmt->execute([$clubSlug]);
$club = $stmt->fetch();

if (!$club) {
    pp_error('Seuraa ei löytynyt', 404);
}

$cacheKey = 'paivan_pelit_' . $clubSlug . '_' . $date;
$ttl = $date === date('Y-m-d') ? 300 : 3600;

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

    $payload = $stmt->fetchColumn();

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

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

$list = pp_api_get('matches-list?date=' . urlencode($date));

if (!$list) {
    pp_error('Otteluita ei saatu haettua', 500, [
        'debug' => $GLOBALS['PP_API_ERROR'] ?? null,
        'matches' => [],
    ]);
}

$search = mb_strtolower(
    (string)($club['search_name'] ?: $club['name']),
    'UTF-8'
);

$matches = [];

foreach (pp_flatten_matches($list) as $match) {
    $home = is_array($match['home'] ?? null) ? $match['home'] : [];
    $away = is_array($match['away'] ?? null) ? $match['away'] : [];

    $homeText = mb_strtolower(
        pp_team_name($home) . ' ' .
        (string)($home['sport_club']['name'] ?? ''),
        'UTF-8'
    );

    $awayText = mb_strtolower(
        pp_team_name($away) . ' ' .
        (string)($away['sport_club']['name'] ?? ''),
        'UTF-8'
    );

    $homeMatch = str_contains($homeText, $search);
    $awayMatch = str_contains($awayText, $search);

    if (!$homeMatch && !$awayMatch) {
        continue;
    }

    $matchId = (int)($match['id'] ?? 0);
    $detail = $matchId > 0
        ? pp_api_get('match?id=' . $matchId)
        : false;

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

    $series = is_array($detail['series'] ?? null)
        ? $detail['series']
        : [];

    $stadium = is_array($detail['stadium'] ?? null)
        ? $detail['stadium']
        : (
            is_array($match['stadium'] ?? null)
                ? $match['stadium']
                : []
        );

    $seriesName = trim((string)(
        $series['custom_name']
        ?? $series['name']
        ?? $series['level']
        ?? ''
    ));

    $phaseName = trim((string)($series['phase'] ?? ''));
    $groupName = trim((string)($match['_group_name'] ?? ''));

    $stadiumName = trim((string)($stadium['name'] ?? ''));
    $stadiumAddress = trim((string)(
        $stadium['address']
        ?? $stadium['details']['address']
        ?? ''
    ));

    $score = pp_score_data($detail);
    $status = pp_match_status($match, $detail);

    $matchDate = (string)(
        $detail['date']
        ?? $match['date']
        ?? ''
    );

    $time = '';

    if ($matchDate !== '') {
        try {
            $dateTime = new DateTimeImmutable($matchDate);
            $dateTime = $dateTime->setTimezone(
                new DateTimeZone('Europe/Helsinki')
            );
            $time = $dateTime->format('H:i');
        } catch (Throwable $e) {
            $time = '';
        }
    }

    $matches[] = [
        'id' => $matchId,
        'date' => $matchDate,
        'time' => $time,

        'series' => $seriesName,
        'phase' => $phaseName,
        'group' => $groupName,

        // Frontendin vanhat fallback-kentät:
        'series_full' => $seriesName,
        'series_name' => $groupName ?: $phaseName,

        'stadium' => [
            'name' => $stadiumName,
            'address' => $stadiumAddress,
            'city' => '',
            'maps_url' => pp_maps_url(
                $stadiumAddress,
                $stadiumName
            ),
        ],

        'stadium_text' => $stadiumName,

        'home' => [
            'name' => pp_team_name($detail['home'] ?? $home),
            'logo' => pp_team_logo($detail['home'] ?? $home),
        ],

        'away' => [
            'name' => pp_team_name($detail['away'] ?? $away),
            'logo' => pp_team_logo($detail['away'] ?? $away),
        ],

        'club_side' => $homeMatch ? 'home' : 'away',
        'status' => $status,

        'result' => $score['result_string'],
        'score' => $score,

        'url' => (string)(
            $match['url']
            ?? (
                $matchId > 0
                    ? 'https://www.pesistulokset.fi/ottelut/' . $matchId
                    : ''
            )
        ),
    ];
}

usort(
    $matches,
    fn(array $a, array $b): int =>
        strcmp((string)$a['date'], (string)$b['date'])
);

$response = [
    'success' => true,
    'date' => $date,
    'club' => [
        'slug' => $club['slug'],
        'name' => $club['name'],
        'color' => $club['primary_color'],
    ],
    'count' => count($matches),
    'matches' => $matches,
    'cache' => [
        'hit' => false,
        'ttl' => $ttl,
    ],
];

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

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

Response::json($response);
