import { database } from "~/database/context";
import * as schema from "~/database/schema";
import { eq, and } from "drizzle-orm";

export async function createDraftPick(data: {
  seasonId: string;
  teamId: string;
  participantId: string;
  pickNumber: number;
  round: number;
  pickInRound: number;
  pickedByUserId: string;
  pickedByType: "owner" | "commissioner" | "auto";
  timeUsed: number;
}) {
  const db = database();
  const [pick] = await db.insert(schema.draftPicks).values(data).returning();
  return pick;
}

export async function getDraftPicks(seasonId: string) {
  const db = database();
  return await db
    .select()
    .from(schema.draftPicks)
    .where(eq(schema.draftPicks.seasonId, seasonId))
    .orderBy(schema.draftPicks.pickNumber);
}

export async function getDraftPickByNumber(seasonId: string, pickNumber: number) {
  const db = database();
  const [pick] = await db
    .select()
    .from(schema.draftPicks)
    .where(
      and(
        eq(schema.draftPicks.seasonId, seasonId),
        eq(schema.draftPicks.pickNumber, pickNumber)
      )
    );
  return pick;
}

export async function getTeamDraftPicks(teamId: string) {
  const db = database();
  return await db
    .select()
    .from(schema.draftPicks)
    .where(eq(schema.draftPicks.teamId, teamId))
    .orderBy(schema.draftPicks.pickNumber);
}

export async function isParticipantDrafted(seasonId: string, participantId: string, providedDb?: ReturnType<typeof database>) {
  const db = providedDb || database();
  const [pick] = await db
    .select()
    .from(schema.draftPicks)
    .where(
      and(
        eq(schema.draftPicks.seasonId, seasonId),
        eq(schema.draftPicks.participantId, participantId)
      )
    );
  return !!pick;
}

/**
 * Get a team's drafted participants grouped by sports season.
 * Returns a map of sportsSeasonId → [{id, name}].
 */
export async function getDraftedParticipantsBySportsSeason(
  teamId: string,
  seasonId: string,
  providedDb?: ReturnType<typeof database>
): Promise<Map<string, Array<{ id: string; name: string }>>> {
  const db = providedDb || database();

  const results = await db
    .select({
      sportsSeasonId: schema.participants.sportsSeasonId,
      participantId: schema.participants.id,
      participantName: schema.participants.name,
    })
    .from(schema.draftPicks)
    .innerJoin(
      schema.participants,
      eq(schema.draftPicks.participantId, schema.participants.id)
    )
    .where(
      and(
        eq(schema.draftPicks.teamId, teamId),
        eq(schema.draftPicks.seasonId, seasonId)
      )
    );

  const map = new Map<string, Array<{ id: string; name: string }>>();
  for (const row of results) {
    if (!map.has(row.sportsSeasonId)) {
      map.set(row.sportsSeasonId, []);
    }
    map.get(row.sportsSeasonId)?.push({ id: row.participantId, name: row.participantName });
  }
  return map;
}

export async function deleteAllDraftPicks(seasonId: string) {
  const db = database();
  await db
    .delete(schema.draftPicks)
    .where(eq(schema.draftPicks.seasonId, seasonId));
}

/**
 * Get all draft picks for a season with participant and sport information
 * Used for draft eligibility calculations
 */
export async function getDraftPicksWithSports(seasonId: string, providedDb?: ReturnType<typeof database>) {
  const db = providedDb || database();
  const results = await db
    .select({
      id: schema.draftPicks.id,
      teamId: schema.draftPicks.teamId,
      pickNumber: schema.draftPicks.pickNumber,
      participantId: schema.participants.id,
      participantName: schema.participants.name,
      sportId: schema.sports.id,
      sportName: schema.sports.name,
    })
    .from(schema.draftPicks)
    .innerJoin(
      schema.participants,
      eq(schema.draftPicks.participantId, schema.participants.id)
    )
    .innerJoin(
      schema.sportsSeasons,
      eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)
    )
    .innerJoin(
      schema.sports,
      eq(schema.sportsSeasons.sportId, schema.sports.id)
    )
    .where(eq(schema.draftPicks.seasonId, seasonId))
    .orderBy(schema.draftPicks.pickNumber);

  // Transform to expected format
  return results.map((r) => ({
    teamId: r.teamId,
    participant: {
      id: r.participantId,
      sport: {
        id: r.sportId,
        name: r.sportName,
      },
    },
  }));
}

/**
 * Get team's draft picks with participant and sport information
 */
export async function getTeamDraftPicksWithSports(teamId: string, seasonId: string, providedDb?: ReturnType<typeof database>) {
  const db = providedDb || database();
  const results = await db
    .select({
      id: schema.draftPicks.id,
      teamId: schema.draftPicks.teamId,
      pickNumber: schema.draftPicks.pickNumber,
      participantId: schema.participants.id,
      participantName: schema.participants.name,
      sportId: schema.sports.id,
      sportName: schema.sports.name,
    })
    .from(schema.draftPicks)
    .innerJoin(
      schema.participants,
      eq(schema.draftPicks.participantId, schema.participants.id)
    )
    .innerJoin(
      schema.sportsSeasons,
      eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)
    )
    .innerJoin(
      schema.sports,
      eq(schema.sportsSeasons.sportId, schema.sports.id)
    )
    .where(
      and(
        eq(schema.draftPicks.teamId, teamId),
        eq(schema.draftPicks.seasonId, seasonId)
      )
    )
    .orderBy(schema.draftPicks.pickNumber);

  // Transform to expected format
  return results.map((r) => ({
    teamId: r.teamId,
    participant: {
      id: r.participantId,
      sport: {
        id: r.sportId,
        name: r.sportName,
      },
    },
  }));
}
