import { database } from "~/database/context";
import * as schema from "~/database/schema";
import { eq, and } from "drizzle-orm";
import type { FetchedStandingsRecord } from "~/services/standings-sync/types";

/**
 * Upsert a pending mapping for an unmatched team from a standings sync.
 * Uses onConflictDoUpdate so re-syncing refreshes the standing data.
 */
export async function upsertPendingStandingsMapping(
  sportsSeasonId: string,
  record: FetchedStandingsRecord,
  providedDb?: ReturnType<typeof database>
) {
  const db = providedDb || database();

  const [row] = await db
    .insert(schema.pendingStandingsMappings)
    .values({
      sportsSeasonId,
      externalTeamId: record.externalTeamId,
      teamName: record.teamName,
      standingData: record as unknown as Record<string, unknown>,
    })
    .onConflictDoUpdate({
      target: [
        schema.pendingStandingsMappings.sportsSeasonId,
        schema.pendingStandingsMappings.externalTeamId,
      ],
      set: {
        teamName: record.teamName,
        standingData: record as unknown as Record<string, unknown>,
      },
    })
    .returning();

  return row;
}

/**
 * Bulk upsert pending mappings for all unmatched teams in a sync.
 */
export async function upsertPendingStandingsMappings(
  sportsSeasonId: string,
  records: FetchedStandingsRecord[],
  providedDb?: ReturnType<typeof database>
) {
  const db = providedDb || database();
  return Promise.all(records.map((r) => upsertPendingStandingsMapping(sportsSeasonId, r, db)));
}

/**
 * Get all pending mappings for a sports season (awaiting admin resolution).
 */
export async function getPendingStandingsMappings(
  sportsSeasonId: string,
  providedDb?: ReturnType<typeof database>
) {
  const db = providedDb || database();

  return db.query.pendingStandingsMappings.findMany({
    where: eq(schema.pendingStandingsMappings.sportsSeasonId, sportsSeasonId),
    orderBy: schema.pendingStandingsMappings.teamName,
  });
}

/**
 * Delete a resolved pending mapping by its externalTeamId.
 */
export async function deletePendingStandingsMapping(
  sportsSeasonId: string,
  externalTeamId: string,
  providedDb?: ReturnType<typeof database>
) {
  const db = providedDb || database();

  await db
    .delete(schema.pendingStandingsMappings)
    .where(
      and(
        eq(schema.pendingStandingsMappings.sportsSeasonId, sportsSeasonId),
        eq(schema.pendingStandingsMappings.externalTeamId, externalTeamId)
      )
    );
}

/**
 * Delete all pending mappings for a sports season.
 * Used when manually clearing the queue.
 */
export async function deleteAllPendingStandingsMappings(
  sportsSeasonId: string,
  providedDb?: ReturnType<typeof database>
) {
  const db = providedDb || database();

  await db
    .delete(schema.pendingStandingsMappings)
    .where(eq(schema.pendingStandingsMappings.sportsSeasonId, sportsSeasonId));
}
