import type {
  Estimate,
  EstimateAssumption,
  EstimateDemandLine,
  EstimateExport,
  EstimateMetric,
  EstimateVersion,
  PrismaClient,
  Project,
  ResourceCostSnapshot,
  ScopeItem,
} from "@capakraken/db";
import type { Prisma } from "@capakraken/db";

export const PROJECT_SNAPSHOT_SELECT = {
  id: true,
  shortCode: true,
  name: true,
  status: true,
  startDate: true,
  endDate: true,
  orderType: true,
  allocationType: true,
  winProbability: true,
  budgetCents: true,
  responsiblePerson: true,
} as const;

export const ESTIMATE_DETAIL_INCLUDE = {
  project: {
    select: {
      id: true,
      shortCode: true,
      name: true,
      status: true,
      startDate: true,
      endDate: true,
    },
  },
  versions: {
    orderBy: { versionNumber: "desc" },
    include: {
      assumptions: {
        orderBy: { sortOrder: "asc" },
      },
      scopeItems: {
        orderBy: { sortOrder: "asc" },
      },
      demandLines: {
        orderBy: { createdAt: "asc" },
      },
      resourceSnapshots: {
        orderBy: { displayName: "asc" },
      },
      metrics: {
        orderBy: { createdAt: "asc" },
      },
      exports: {
        orderBy: { createdAt: "desc" },
      },
    },
  },
} as const;

export interface EstimateVersionDetails extends EstimateVersion {
  assumptions: EstimateAssumption[];
  scopeItems: ScopeItem[];
  demandLines: EstimateDemandLine[];
  resourceSnapshots: ResourceCostSnapshot[];
  metrics: EstimateMetric[];
  exports: EstimateExport[];
}

export interface EstimateWithDetails extends Estimate {
  project?: Pick<Project, "id" | "shortCode" | "name" | "status" | "startDate" | "endDate"> | null;
  versions: EstimateVersionDetails[];
}

export interface EstimateListItem extends Estimate {
  project?: Pick<Project, "id" | "shortCode" | "name" | "status"> | null;
  versions: Array<
    Pick<
      EstimateVersion,
      "id" | "versionNumber" | "label" | "status" | "updatedAt"
    >
  >;
}

export type EstimateDbClient = PrismaClient;

export async function buildProjectSnapshot(
  db: Pick<PrismaClient, "project">,
  projectId: string | null | undefined,
): Promise<Prisma.InputJsonValue> {
  if (!projectId) {
    return {};
  }

  const project = await db.project.findUnique({
    where: { id: projectId },
    select: PROJECT_SNAPSHOT_SELECT,
  });

  if (!project) {
    return {};
  }

  return {
    ...project,
    startDate: project.startDate.toISOString(),
    endDate: project.endDate.toISOString(),
  } satisfies Prisma.InputJsonValue;
}
