/**
 * Porta da fonte de dados de futebol.
 *
 * Existe para o token da `football-data.org` não bloquear o resto do backlog:
 * o adaptador falso (`FonteFakeAdapter`) entrega jogos fixos do Brasileirão, e
 * quando o token chegar troca-se apenas o provider no módulo. Nenhum service
 * de domínio conhece o fornecedor.
 */

export const FONTE_DADOS = Symbol('FONTE_DADOS');

export interface CompeticaoExterna {
  code: string;
  nome: string;
  /** Última rodada com jogos publicados. */
  rodadaAtual: number | null;
  totalRodadas: number;
}

export interface JogoExterno {
  /** Identificador na fonte — chave para detectar mudança depois (PP-10). */
  externalId: string;
  competitionCode: string;
  rodada: number;
  timeCasa: string;
  timeFora: string;
  /** Horário oficial de início, em UTC. */
  inicioEm: Date;
  status:
    | 'SCHEDULED'
    | 'TIMED'
    | 'IN_PLAY'
    | 'PAUSED'
    | 'FINISHED'
    | 'POSTPONED'
    | 'SUSPENDED'
    | 'CANCELLED';
  golsCasa: number | null;
  golsFora: number | null;
  /** Quando a fonte alterou este registro por último, se ela informar. */
  atualizadoEm: Date | null;
}

/** Erro de indisponibilidade da fonte, para o domínio distinguir de erro nosso. */
export class FonteIndisponivelError extends Error {
  constructor(motivo: string) {
    super(`fonte de dados indisponível: ${motivo}`);
    this.name = 'FonteIndisponivelError';
  }
}

export interface FonteDeDados {
  listarCompeticoes(): Promise<CompeticaoExterna[]>;

  /**
   * Jogos de um intervalo de rodadas, inclusive nas duas pontas.
   * Lança `FonteIndisponivelError` quando não conseguir responder — quem chama
   * precisa poder decidir entre abortar e seguir com o que tem.
   */
  listarJogos(
    competitionCode: string,
    rodadaInicial: number,
    rodadaFinal: number,
  ): Promise<JogoExterno[]>;
}
