import "server-only";

import { prisma } from "@/lib/prisma";
import { MAX_CONTRACT_PDF_BYTES, storeContractDocumentFile } from "@/lib/contracts/storage";
import { readStoredProposalDocument } from "@/lib/proposals/storage";

type ProposalPdfDocument = {
  id: string;
  fileName: string;
  filePath: string;
  mimeType: string;
  sizeBytes: number;
  checksumSha256: string | null;
  createdAt: Date;
};

export type ProposalPdfSource = {
  proposal: {
    id: string;
    title: string;
  };
  document: ProposalPdfDocument;
  fileBuffer: Buffer;
};

export type ProposalPdfLookupResult =
  | { status: "proposal_not_found" }
  | { status: "pdf_not_found"; proposal: { id: string; title: string } }
  | { status: "ok"; source: ProposalPdfSource };

export function isPdfProposalDocument(document: { fileName: string; mimeType: string }) {
  return document.mimeType === "application/pdf" || document.fileName.toLowerCase().endsWith(".pdf");
}

export async function getLatestProposalPdfSourceForUser(userId: string, proposalId: string): Promise<ProposalPdfLookupResult> {
  const proposal = await prisma.proposal.findFirst({
    where: {
      id: proposalId,
      userId,
    },
    select: {
      id: true,
      title: true,
      documents: {
        orderBy: [{ createdAt: "desc" }],
        select: {
          id: true,
          fileName: true,
          filePath: true,
          mimeType: true,
          sizeBytes: true,
          checksumSha256: true,
          createdAt: true,
        },
      },
    },
  });

  if (!proposal) {
    return { status: "proposal_not_found" };
  }

  const latestPdf = proposal.documents.find((item) => isPdfProposalDocument(item)) ?? null;
  if (!latestPdf) {
    return {
      status: "pdf_not_found",
      proposal: {
        id: proposal.id,
        title: proposal.title,
      },
    };
  }

  const fileBuffer = await readStoredProposalDocument(latestPdf.filePath, MAX_CONTRACT_PDF_BYTES);
  return {
    status: "ok",
    source: {
      proposal: {
        id: proposal.id,
        title: proposal.title,
      },
      document: latestPdf,
      fileBuffer,
    },
  };
}

export async function ensureProposalPdfLinkedToContract(args: {
  userId: string;
  contractId: string;
  source: ProposalPdfSource;
}) {
  const { userId, contractId, source } = args;

  const recentDocuments = await prisma.contractDocument.findMany({
    where: {
      contractId,
    },
    orderBy: [{ createdAt: "desc" }],
    take: 25,
    select: {
      id: true,
      fileName: true,
      sizeBytes: true,
      checksumSha256: true,
    },
  });

  const duplicate = recentDocuments.find((item) => {
    if (source.document.checksumSha256 && item.checksumSha256) {
      return source.document.checksumSha256 === item.checksumSha256;
    }

    return item.fileName === source.document.fileName && item.sizeBytes === source.document.sizeBytes;
  });

  if (duplicate) {
    return {
      created: false,
      documentId: duplicate.id,
    };
  }

  const stored = await storeContractDocumentFile(userId, contractId, source.document.fileName, source.document.mimeType, source.fileBuffer);
  const created = await prisma.contractDocument.create({
    data: {
      contractId,
      fileName: stored.fileName,
      filePath: stored.filePath,
      mimeType: stored.mimeType,
      sizeBytes: stored.sizeBytes,
      checksumSha256: stored.checksumSha256,
      kind: "SIGNED_CONTRACT",
    },
    select: {
      id: true,
    },
  });

  return {
    created: true,
    documentId: created.id,
  };
}
