import React, { createContext, useContext, useState, ReactNode, useMemo } from 'react';
import { Team, Round, TeamScore, Match, MatchResult } from '@/types/tournament';
import { generateMatches, createNextRoundMatches } from '@/utils/tournamentUtils';

interface TournamentContextType {
  teams: Team[];
  fieldCount: number;
  rounds: Round[];
  currentRound: Round | null;
  addTeam: (team: Omit<Team, 'id'>) => void;
  removeTeam: (id: string) => void;
  setFieldCount: (count: number) => void;
  resetTournament: () => void;
  startNewRound: () => void;
  updateMatchResult: (matchId: string, scoreA: number, scoreB: number) => void;
  completeCurrentRound: () => void;
  getTeamScores: (league: 'bundesliga' | 'champions') => TeamScore[];
}

const TournamentContext = createContext<TournamentContextType | undefined>(undefined);

export const TournamentProvider = ({ children }: { children: ReactNode }) => {
  const [teams, setTeams] = useState<Team[]>([]);
  const [fieldCount, setFieldCountState] = useState<number>(4);
  const [rounds, setRounds] = useState<Round[]>([]);

  const currentRound = useMemo(() => {
    return rounds.find((r) => !r.completed) || null;
  }, [rounds]);

  const addTeam = (team: Omit<Team, 'id'>) => {
    const newTeam: Team = {
      ...team,
      id: crypto.randomUUID(),
    };
    setTeams((prev) => [...prev, newTeam]);
  };

  const removeTeam = (id: string) => {
    setTeams((prev) => prev.filter((team) => team.id !== id));
  };

  const setFieldCount = (count: number) => {
    setFieldCountState(Math.max(1, count));
  };

  const resetTournament = () => {
    setTeams([]);
    setFieldCountState(4);
    setRounds([]);
  };

  const startNewRound = () => {
    if (currentRound && !currentRound.completed) return;

    let state;

    if (rounds.length === 0) {
      // First round: initial random generation
      state = generateMatches(teams, fieldCount);
    } else {
      // Subsequent rounds: rotation system
      const lastRound = rounds[rounds.length - 1];
      state = createNextRoundMatches(lastRound, fieldCount);
    }

    const allMatches = [...state.bundesligaMatches, ...state.championsMatches];

    const newRound: Round = {
      id: crypto.randomUUID(),
      roundNumber: rounds.length + 1,
      matches: allMatches,
      bundesligaWaiting: state.bundesligaWaiting,
      championsWaiting: state.championsWaiting,
      completed: false,
    };

    setRounds((prev) => [...prev, newRound]);
  };

  const updateMatchResult = (matchId: string, scoreA: number, scoreB: number) => {
    const diff = Math.abs(scoreB - scoreA);
    
    let pointsA: number;
    let pointsB: number;
    
    if (scoreA > scoreB) {
      // Team A gewinnt
      pointsA = diff + 2;
      pointsB = -diff;
    } else {
      // Team B gewinnt
      pointsA = -diff;
      pointsB = diff + 2;
    }
    
    const result: MatchResult = {
      scoreA,
      scoreB,
      pointsA,
      pointsB,
    };

    setRounds((prev) =>
      prev.map((round) => ({
        ...round,
        matches: round.matches.map((match) =>
          match.id === matchId ? { ...match, result } : match
        ),
      }))
    );
  };

  const completeCurrentRound = () => {
    if (!currentRound) return;

    // Check if all matches have results
    const allMatchesHaveResults = currentRound.matches.every((m) => m.result);
    if (!allMatchesHaveResults) return;

    setRounds((prev) =>
      prev.map((round) =>
        round.id === currentRound.id ? { ...round, completed: true } : round
      )
    );
  };

  const getTeamScores = (league: 'bundesliga' | 'champions'): TeamScore[] => {
    const leagueTeams = teams.filter((t) => t.league === league);

    return leagueTeams.map((team) => {
      const pointsHistory: number[] = [];
      let totalPoints = 0;
      let matchesPlayed = 0;

      rounds.forEach((round) => {
        let roundPoints = 0;
        round.matches.forEach((match) => {
          if (match.result) {
            if (match.teamA.id === team.id) {
              roundPoints += match.result.pointsA;
              matchesPlayed++;
            } else if (match.teamB.id === team.id) {
              roundPoints += match.result.pointsB;
              matchesPlayed++;
            }
          }
        });
        pointsHistory.push(roundPoints);
        totalPoints += roundPoints;
      });

      return {
        team,
        totalPoints,
        pointsHistory,
        matchesPlayed,
      };
    }).sort((a, b) => b.totalPoints - a.totalPoints);
  };

  return (
    <TournamentContext.Provider
      value={{
        teams,
        fieldCount,
        rounds,
        currentRound,
        addTeam,
        removeTeam,
        setFieldCount,
        resetTournament,
        startNewRound,
        updateMatchResult,
        completeCurrentRound,
        getTeamScores,
      }}
    >
      {children}
    </TournamentContext.Provider>
  );
};

export const useTournament = () => {
  const context = useContext(TournamentContext);
  if (!context) {
    throw new Error('useTournament must be used within a TournamentProvider');
  }
  return context;
};
