import type { PrismaClient } from "@capakraken/db";
import type { ValueScoreBreakdown } from "@capakraken/shared";

export interface GetDashboardTopValueResourcesInput {
  limit: number;
  userRole: string;
}

export interface DashboardTopValueResourceRow {
  id: string;
  eid: string;
  displayName: string;
  chapter: string | null;
  valueScore: number | null;
  valueScoreBreakdown: ValueScoreBreakdown | null;
  valueScoreUpdatedAt: Date | null;
  lcrCents: number;
  countryCode: string | null;
  countryName: string | null;
  federalState: string | null;
  metroCityName: string | null;
}

function isValueScoreBreakdown(value: unknown): value is ValueScoreBreakdown {
  if (typeof value !== "object" || value === null) {
    return false;
  }

  return [
    "skillDepth",
    "skillBreadth",
    "costEfficiency",
    "chargeability",
    "experience",
    "total",
  ].every((key) => typeof (value as Record<string, unknown>)[key] === "number");
}

function normalizeValueScoreBreakdown(value: unknown): ValueScoreBreakdown | null {
  return isValueScoreBreakdown(value) ? value : null;
}

export async function getDashboardTopValueResources(
  db: PrismaClient,
  input: GetDashboardTopValueResourcesInput,
): Promise<DashboardTopValueResourceRow[]> {
  const settings = await db.systemSettings.findUnique({
    where: { id: "singleton" },
  });

  const visibleRoles =
    (settings?.scoreVisibleRoles as unknown as string[]) ?? ["ADMIN", "MANAGER"];

  if (!visibleRoles.includes(input.userRole)) {
    return [];
  }

  return db.resource.findMany({
    where: { isActive: true, valueScore: { not: null } },
    select: {
      id: true,
      eid: true,
      displayName: true,
      chapter: true,
      valueScore: true,
      valueScoreBreakdown: true,
      valueScoreUpdatedAt: true,
      lcrCents: true,
      country: {
        select: {
          code: true,
          name: true,
        },
      },
      federalState: true,
      metroCity: {
        select: {
          name: true,
        },
      },
    },
    orderBy: { valueScore: "desc" },
    take: input.limit,
  }).then((resources) => resources.map((resource) => ({
    id: resource.id,
    eid: resource.eid,
    displayName: resource.displayName,
    chapter: resource.chapter,
    valueScore: resource.valueScore,
    valueScoreBreakdown: normalizeValueScoreBreakdown(resource.valueScoreBreakdown),
    valueScoreUpdatedAt: resource.valueScoreUpdatedAt,
    lcrCents: resource.lcrCents,
    countryCode: resource.country?.code ?? null,
    countryName: resource.country?.name ?? null,
    federalState: resource.federalState ?? null,
    metroCityName: resource.metroCity?.name ?? null,
  })));
}
