import { logger } from "@/lib/logger";
import PocketBase from "pocketbase";
import { transformMatch, transformTeam, transformTeamInfo } from "@/lib/pocketbase/util/transform-types";
import { Team, TeamInfo, TeamInput, TeamUpdateInput, TeamStats } from "@/features/teams/types";
import { Match } from "@/features/matches/types";

export function createTeamsService(pb: PocketBase) {
  return {
    async getTeamInfo(id: string): Promise<TeamInfo> {
      const result = await pb.collection("teams").getOne(id, {
        fields: "id,name,primary_color,accent_color,logo",
        expand: "players"
      });
      return transformTeamInfo(result);
    },

    async listTeamInfos(): Promise<TeamInfo[]> {
      logger.info("PocketBase | Listing team infos");
      const result = await pb.collection("teams").getFullList({
        fields: "id,name,primary_color,accent_color,logo",
        expand: "players"
      });
      return result.map(transformTeamInfo);
    },

    async getTeam(id: string): Promise<Team | null> {
      const result = await pb.collection("teams").getOne(id, {
        expand: "players, tournaments",
      });
      return transformTeam(result);
    },

    async createTeam(data: TeamInput): Promise<Team> {
      logger.info("PocketBase | Creating team", data);
      
      try {
        if (data.players.length > 0) {
          const playerFilter = data.players
            .map((playerId) => `id = "${playerId}"`)
            .join(" || ");
          const existingPlayers = await pb.collection("players").getFullList({
            filter: playerFilter,
            fields: "id",
          });

          if (existingPlayers.length !== data.players.length) {
            const foundIds = new Set(existingPlayers.map((player) => player.id));
            const missingId = data.players.find((playerId) => !foundIds.has(playerId));
            throw new Error(`Player with ID ${missingId} not found`);
          }
        }

        const result = await pb.collection("teams").create({
          ...data,
          players: data.players
        });

        await Promise.all(
          data.players.map((playerId) =>
            pb.collection("players").update(playerId, {
              "teams+": result.id
            })
          )
        );

        return transformTeam(await pb.collection("teams").getOne(result.id, {
          expand: "players, tournaments"
        }));
      } catch (error) {
        logger.error("PocketBase | Error creating team", error);
        throw error;
      }
    },

    async updateTeam(id: string, data: TeamUpdateInput): Promise<Team> {
      logger.info("PocketBase | Updating team", { id, updates: Object.keys(data) });

      try {
        const existingTeam = await pb.collection("teams").getOne(id).catch(() => null);
        if (!existingTeam) {
          throw new Error(`Team with ID ${id} not found`);
        }

        const result = await pb.collection("teams").update(id, data);

        const updated = await pb.collection("teams").getOne(result.id, {
          expand: "players, tournaments",
          // @ts-ignore - Add cache busting
          $cancelKey: Date.now().toString()
        });

        return transformTeam(updated);
      } catch (error) {
        logger.error("PocketBase | Error updating team", error);
        throw error;
      }
    },

    async getTeamStats(id: string): Promise<TeamStats | null> {
      try {
        const result = await pb.collection("team_stats").getFirstListItem(`team_id="${id}"`);
        return result as unknown as TeamStats;
      } catch (error) {
        logger.info("PocketBase | No team stats found", id);
        return null;
      }
    },

    async getTeamMatches(teamId: string): Promise<Match[]> {
      const teamFilter = `home = "${teamId}" || away = "${teamId}"`

      const result = await pb.collection("matches").getFullList({
        filter: `(${teamFilter}) && (status = "ended" || status = "started")`,
        sort: "-start_time",
        expand: "tournament,home,away,home.players,away.players",
      });

      return result.map((match) => transformMatch(match));
    },

    async getTeamsWithFilter(filter: string, expand?: string): Promise<any[]> {
      logger.info("PocketBase | Getting teams with filter", { filter, expand });
      const result = await pb.collection("teams").getFullList({
        filter,
        expand,
      });
      return result;
    },
  };
}
