import { NextResponse } from 'next/server';
import { z } from 'zod';
import { and, eq } from 'drizzle-orm';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { parseBody } from '@/lib/api/route-helpers';
import { db } from '@/lib/db';
import { documentTemplates } from '@/lib/db/schema/documents';
import { errorResponse, NotFoundError, ValidationError } from '@/lib/errors';
import { generateEoiPdfFromTemplate } from '@/lib/pdf/fill-eoi-form';
import { buildEoiContext } from '@/lib/services/eoi-context';
import { getStorageBackend, presignDownloadUrl } from '@/lib/storage';
import { buildStoragePath } from '@/lib/minio';

const previewBodySchema = z.object({
  interestId: z.string().uuid(),
  dimensionUnit: z.enum(['ft', 'm']).optional(),
});

/**
 * Phase 7.2 - live preview endpoint for the PDF editor.
 *
 * Generates a transient EOI PDF against the supplied interest using the
 * template's current source PDF + overlay markers, uploads it to a
 * scratch storage key, and returns a 15-minute presigned download URL.
 *
 * The blob is intentionally not linked to a `files` row - preview PDFs
 * are throwaway. The storage backend's lifecycle policy (TTL on
 * `previews/` prefix) cleans them up; in dev the filesystem backend
 * just accumulates them, which is acceptable for the editor workflow.
 */
export const POST = withAuth(
  withPermission('documents', 'create', async (req, ctx, params) => {
    try {
      const body = await parseBody(req, previewBodySchema);

      const template = await db.query.documentTemplates.findFirst({
        where: and(eq(documentTemplates.id, params.id!), eq(documentTemplates.portId, ctx.portId)),
      });
      if (!template) throw new NotFoundError('Template');
      if (template.templateType !== 'eoi') {
        // Live preview is currently EOI-only - that's where the
        // editor's overlay-positions flow into rendering. Other
        // template types are deferred (no in-app fill yet).
        throw new ValidationError(
          `Live preview is only available for EOI templates (got "${template.templateType}").`,
        );
      }

      const eoiContext = await buildEoiContext(body.interestId, ctx.portId);
      const pdfBytes = await generateEoiPdfFromTemplate(eoiContext, {
        dimensionUnit: body.dimensionUnit ?? eoiContext.yacht?.lengthUnit ?? 'ft',
      });

      const previewKey = buildStoragePath(
        ctx.portSlug,
        'previews',
        'document-templates',
        template.id,
        `${crypto.randomUUID()}.pdf`,
      );
      const backend = await getStorageBackend();
      const buffer = Buffer.from(pdfBytes);
      await backend.put(previewKey, buffer, {
        contentType: 'application/pdf',
        sizeBytes: buffer.length,
      });

      const previewUrl = await presignDownloadUrl(
        previewKey,
        900,
        `${template.name}.preview.pdf`,
        ctx.portSlug,
      );
      return NextResponse.json({ data: { previewUrl } });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
