import "server-only";

import { Prisma, type ProposalStatus } from "@prisma/client";
import { prisma } from "@/lib/prisma";
import type { ProposalDocumentView, ProposalView } from "@/lib/proposals/types";

type ProposalDocumentRecord = {
  id: string;
  fileName: string;
  mimeType: string;
  sizeBytes: number;
  createdAt: Date;
};

type ProposalWithProgress = {
  id: string;
  title: string;
  issuingEntity: string;
  summary: string;
  currentStep: number;
  completionPercent: number;
  readyForSubmissionAt: Date | null;
  status: ProposalStatus;
  sourceLicitationId: string | null;
  createdAt: Date;
  updatedAt: Date;
  documents: ProposalDocumentRecord[];
};

type LegacyProposal = Omit<ProposalWithProgress, "currentStep" | "completionPercent" | "readyForSubmissionAt">;

function isLegacyWorkflowSchemaError(error: unknown) {
  return error instanceof Prisma.PrismaClientKnownRequestError && (error.code === "P2021" || error.code === "P2022");
}

function toDocumentView(document: ProposalDocumentRecord): ProposalDocumentView {
  return {
    id: document.id,
    fileName: document.fileName,
    mimeType: document.mimeType,
    sizeBytes: document.sizeBytes,
    createdAt: document.createdAt.toISOString(),
  };
}

function toProposalView(item: ProposalWithProgress): ProposalView {
  return {
    id: item.id,
    title: item.title,
    issuingEntity: item.issuingEntity,
    summary: item.summary,
    currentStep: item.currentStep,
    completionPercent: item.completionPercent,
    readyForSubmissionAt: item.readyForSubmissionAt ? item.readyForSubmissionAt.toISOString() : null,
    status: item.status,
    sourceLicitationId: item.sourceLicitationId,
    createdAt: item.createdAt.toISOString(),
    updatedAt: item.updatedAt.toISOString(),
    documents: item.documents.map(toDocumentView),
  };
}

function toLegacyProposalView(item: LegacyProposal): ProposalView {
  return {
    id: item.id,
    title: item.title,
    issuingEntity: item.issuingEntity,
    summary: item.summary,
    currentStep: 1,
    completionPercent: 0,
    readyForSubmissionAt: null,
    status: item.status,
    sourceLicitationId: item.sourceLicitationId,
    createdAt: item.createdAt.toISOString(),
    updatedAt: item.updatedAt.toISOString(),
    documents: item.documents.map(toDocumentView),
  };
}

export async function listUserProposals(userId: string, search: string) {
  const normalized = search.trim();
  const where = {
    userId,
    ...(normalized
      ? {
          OR: [
            { title: { contains: normalized, mode: "insensitive" as const } },
            { issuingEntity: { contains: normalized, mode: "insensitive" as const } },
            { summary: { contains: normalized, mode: "insensitive" as const } },
          ],
        }
      : {}),
  };
  const orderBy = [{ updatedAt: "desc" as const }, { createdAt: "desc" as const }];

  try {
    const rows = await prisma.proposal.findMany({
      where,
      orderBy,
      select: {
        id: true,
        title: true,
        issuingEntity: true,
        summary: true,
        currentStep: true,
        completionPercent: true,
        readyForSubmissionAt: true,
        status: true,
        sourceLicitationId: true,
        createdAt: true,
        updatedAt: true,
        documents: {
          orderBy: [{ createdAt: "desc" }],
          select: {
            id: true,
            fileName: true,
            mimeType: true,
            sizeBytes: true,
            createdAt: true,
          },
        },
      },
    });

    return rows.map(toProposalView);
  } catch (error) {
    if (!isLegacyWorkflowSchemaError(error)) {
      throw error;
    }

    const rows = await prisma.proposal.findMany({
      where,
      orderBy,
      select: {
        id: true,
        title: true,
        issuingEntity: true,
        summary: true,
        status: true,
        sourceLicitationId: true,
        createdAt: true,
        updatedAt: true,
        documents: {
          orderBy: [{ createdAt: "desc" }],
          select: {
            id: true,
            fileName: true,
            mimeType: true,
            sizeBytes: true,
            createdAt: true,
          },
        },
      },
    });

    return rows.map(toLegacyProposalView);
  }
}
