import type { FetchedStandingsRecord, StandingsSyncAdapter } from "./types";

const EPL_STANDINGS_URL = "https://api.football-data.org/v4/competitions/PL/standings";

interface FootballDataTeam {
  id: number;
  name: string;
  shortName?: string;
  tla?: string;
}

interface FootballDataTableEntry {
  position: number;
  team: FootballDataTeam;
  playedGames: number;
  form?: string | null;
  won: number;
  draw: number;
  lost: number;
  points: number;
  goalsFor: number;
  goalsAgainst: number;
  goalDifference: number;
}

interface FootballDataStanding {
  type: "TOTAL" | "HOME" | "AWAY" | string;
  table: FootballDataTableEntry[];
}

interface FootballDataStandingsResponse {
  standings: FootballDataStanding[];
}

/**
 * English Premier League standings adapter backed by football-data.org.
 *
 * Endpoint: GET /v4/competitions/PL/standings
 * Required env var: FOOTBALL_DATA_API_KEY
 */
export class EplStandingsAdapter implements StandingsSyncAdapter {
  constructor(private readonly apiKey = process.env.FOOTBALL_DATA_API_KEY) {}

  async fetchStandings(): Promise<FetchedStandingsRecord[]> {
    if (!this.apiKey) {
      throw new Error(
        "FOOTBALL_DATA_API_KEY is required to sync EPL standings from football-data.org."
      );
    }

    const response = await fetch(EPL_STANDINGS_URL, {
      headers: {
        "X-Auth-Token": this.apiKey,
      },
    });

    if (!response.ok) {
      throw new Error(
        `football-data.org EPL standings API returned ${response.status}: ${response.statusText}`
      );
    }

    const json = (await response.json()) as FootballDataStandingsResponse;
    const total = json.standings?.find((standing) => standing.type === "TOTAL");
    const table = total?.table ?? [];

    if (table.length === 0) {
      throw new Error(
        "football-data.org EPL standings API returned no TOTAL table entries — response shape may have changed"
      );
    }

    return table
      .toSorted((a, b) => a.position - b.position)
      .map((entry): FetchedStandingsRecord => ({
        teamName: entry.team.name,
        externalTeamId: String(entry.team.id),
        wins: entry.won,
        losses: entry.lost,
        ties: entry.draw,
        tablePoints: entry.points,
        goalsFor: entry.goalsFor,
        goalsAgainst: entry.goalsAgainst,
        goalDifference: entry.goalDifference,
        winPct: entry.playedGames > 0 ? entry.won / entry.playedGames : 0,
        gamesPlayed: entry.playedGames,
        leagueRank: entry.position,
        lastTen: entry.form ?? undefined,
      }));
  }
}
