<?php

namespace App\Libraries;

use App\Models\FootballFixtureModel;
use App\Models\FootballLeagueModel;
use App\Models\FootballTeamModel;

/**
 * Attach team/league logo URLs to tip match legs (read-time enrichment).
 */
class FootballMatchLogoResolver
{
    protected FootballFixtureModel $fixtureModel;
    protected FootballTeamModel $teamModel;
    protected FootballLeagueModel $leagueModel;

    /** @var array<string, ?string> */
    protected array $teamLogoCache = [];

    /** @var array<string, ?string> */
    protected array $leagueLogoCache = [];

    public function __construct()
    {
        $this->fixtureModel = new FootballFixtureModel();
        $this->teamModel = new FootballTeamModel();
        $this->leagueModel = new FootballLeagueModel();
    }

    /**
     * @param list<array<string, mixed>> $legs
     * @return list<array<string, mixed>>
     */
    public function enrichLegs(array $legs): array
    {
        $out = [];
        foreach ($legs as $leg) {
            $out[] = $this->enrichLeg(is_array($leg) ? $leg : []);
        }

        return $out;
    }

    /**
     * @param array<string, mixed> $leg
     * @return array<string, mixed>
     */
    public function enrichLeg(array $leg): array
    {
        if ($this->hasLogos($leg)) {
            return $leg;
        }

        if (!empty($leg['fixture_id'])) {
            $row = $this->fixtureModel->findWithLogosByApiFixtureId((int) $leg['fixture_id']);
            if ($row) {
                $leg['team1_logo'] = $leg['team1_logo'] ?? ($row['home_logo'] ?? null);
                $leg['team2_logo'] = $leg['team2_logo'] ?? ($row['away_logo'] ?? null);
                $leg['league_logo'] = $leg['league_logo'] ?? ($row['league_logo'] ?? null);
            }
        }

        if (empty($leg['team1_logo']) && !empty($leg['team1'])) {
            $leg['team1_logo'] = $this->logoForTeamName((string) $leg['team1']);
        }
        if (empty($leg['team2_logo']) && !empty($leg['team2'])) {
            $leg['team2_logo'] = $this->logoForTeamName((string) $leg['team2']);
        }
        if (empty($leg['league_logo']) && !empty($leg['league'])) {
            $leg['league_logo'] = $this->logoForLeagueLabel((string) $leg['league']);
        }

        return $leg;
    }

  /**
     * @param array<string, mixed> $leg
     */
    protected function hasLogos(array $leg): bool
    {
        return !empty($leg['team1_logo']) && !empty($leg['team2_logo']);
    }

    protected function logoForTeamName(string $name): ?string
    {
        $key = $this->normalizeKey($name);
        if ($key === '') {
            return null;
        }
        if (array_key_exists($key, $this->teamLogoCache)) {
            return $this->teamLogoCache[$key];
        }

        $logo = $this->teamModel->findLogoByName($name);
        $this->teamLogoCache[$key] = $logo;

        return $logo;
    }

    protected function logoForLeagueLabel(string $label): ?string
    {
        $key = $this->normalizeKey($label);
        if ($key === '') {
            return null;
        }
        if (array_key_exists($key, $this->leagueLogoCache)) {
            return $this->leagueLogoCache[$key];
        }

        $logo = $this->leagueModel->findLogoByLabel($label);
        $this->leagueLogoCache[$key] = $logo;

        return $logo;
    }

    protected function normalizeKey(string $value): string
    {
        return mb_strtolower(trim($value));
    }
}
