import { auth } from '@/lib/auth';
import { db } from '@/lib/db';
import { documents, users, getFieldType } from '@/lib/db/schema';
import type { DocumentSigner } from '@/lib/db/schema';
import { eq } from 'drizzle-orm';
import { preparePdf } from '@/lib/pdf/prepare-document';
import { logAuditEvent } from '@/lib/signing/audit';
import path from 'node:path';

const UPLOADS_DIR = path.join(process.cwd(), 'uploads');

export async function POST(
  req: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  const session = await auth();
  if (!session?.user?.id) return new Response('Unauthorized', { status: 401 });

  const { id } = await params;
  const body = await req.json() as {
    textFillData?: Record<string, string>;
    assignedClientId?: string;
    /** Email addresses to send the document to (client email + any CC addresses). */
    emailAddresses?: string[];
    /** Multi-signer list with assigned colors. Saved to documents.signers. */
    signers?: DocumentSigner[];
  };

  const doc = await db.query.documents.findFirst({ where: eq(documents.id, id) });
  if (!doc) return Response.json({ error: 'Not found' }, { status: 404 });
  if (!doc.filePath) return Response.json({ error: 'Document has no PDF file' }, { status: 422 });

  const srcPath = path.join(UPLOADS_DIR, doc.filePath);
  // Prepared variant stored next to original with _prepared suffix
  const preparedRelPath = doc.filePath.replace(/\.pdf$/, '_prepared.pdf');
  const destPath = path.join(UPLOADS_DIR, preparedRelPath);

  // Path traversal guard
  if (!destPath.startsWith(UPLOADS_DIR)) {
    return new Response('Forbidden', { status: 403 });
  }

  const sigFields = (doc.signatureFields as import('@/lib/db/schema').SignatureFieldData[]) ?? [];
  const textFields = body.textFillData ?? {};

  // Fetch agent's saved signature and initials for embedding at agent-owned field coordinates
  const agentUser = await db.query.users.findFirst({
    where: eq(users.id, session.user.id),
    columns: { agentSignatureData: true, agentInitialsData: true },
  });
  const agentSignatureData = agentUser?.agentSignatureData ?? null;
  const agentInitialsData = agentUser?.agentInitialsData ?? null;

  // Guard: if document has agent-signature fields but no signature saved, block prepare
  const hasAgentSigFields = sigFields.some(f => getFieldType(f) === 'agent-signature');
  if (hasAgentSigFields && !agentSignatureData) {
    return Response.json(
      { error: 'agent-signature-missing', message: 'No agent signature saved. Go to Profile to save your signature first.' },
      { status: 422 }
    );
  }

  // Guard: agent-initials fields present but no initials saved
  const hasAgentInitialsFields = sigFields.some(f => getFieldType(f) === 'agent-initials');
  if (hasAgentInitialsFields && !agentInitialsData) {
    return Response.json(
      { error: 'agent-initials-missing', message: 'No agent initials saved. Go to Profile to save your initials first.' },
      { status: 422 }
    );
  }

  await preparePdf(srcPath, destPath, textFields, sigFields, agentSignatureData, agentInitialsData);

  const [updated] = await db
    .update(documents)
    .set({
      preparedFilePath: preparedRelPath,
      textFillData: body.textFillData ?? null,
      assignedClientId: body.assignedClientId ?? doc.assignedClientId ?? null,
      emailAddresses: body.emailAddresses ?? null,
      // Persist signer list if provided — required before send route reads documents.signers
      ...(body.signers !== undefined ? { signers: body.signers } : {}),
      status: 'Sent',
      sentAt: new Date(),
    })
    .where(eq(documents.id, id))
    .returning();

  await logAuditEvent({ documentId: id, eventType: 'document_prepared' });

  return Response.json(updated);
}
