import { NextResponse } from 'next/server';
import { z } from 'zod';
import { sql } from 'drizzle-orm';
import { db } from '@server/db/drizzle';
import { withErrorHandler, RouteContext } from '@server/middleware/withErrorHandler';
import { withAuth, AuthedRequest } from '@server/middleware/withAuth';
import { ForbiddenError, NotFoundError, ValidationError } from '@server/errors';
import { initDatabase } from '@server/db/init';
import { getDefaultTemplate } from '@server/services/email/templates';
import { renderTemplate } from '@server/services/email/render';

function requireAdmin(req: AuthedRequest) {
  if (req.session.role !== 'superadmin' && req.session.role !== 'support') throw new ForbiddenError();
}

export const GET = withErrorHandler(
  withAuth(async (req: AuthedRequest, ctx: RouteContext) => {
    requireAdmin(req);
    await initDatabase();
    const { key } = await ctx.params;
    const def = getDefaultTemplate(key);
    if (!def) throw new NotFoundError('Template');

    const { rows } = await db.execute(sql`SELECT subject, html, updated_at FROM email_templates WHERE key = ${key} LIMIT 1`);
    const o = rows[0] as { subject: string; html: string; updated_at: string } | undefined;

    const subject = o?.subject ?? def.subject;
    const body = o?.html ?? def.body;
    const previewVars = def.sampleVars ?? {};
    const preview = await renderTemplate(key, previewVars);

    return NextResponse.json({
      key, audience: def.audience,
      subject, html: body,
      defaultSubject: def.subject, defaultHtml: def.body,
      sampleVars: previewVars,
      preview: { subject: preview.subject, html: preview.html },
      overridden: !!o,
      updatedAt: o?.updated_at ?? null,
    });
  })
);

const putSchema = z.object({
  subject: z.string().min(1),
  html: z.string().min(1),
});

export const PUT = withErrorHandler(
  withAuth(async (req: AuthedRequest, ctx: RouteContext) => {
    requireAdmin(req);
    await initDatabase();
    const { key } = await ctx.params;
    if (!getDefaultTemplate(key)) throw new NotFoundError('Template');
    const body = await req.json();
    const parsed = putSchema.safeParse(body);
    if (!parsed.success) throw new ValidationError(parsed.error.issues[0]?.message || 'Invalid input');

    await db.execute(sql`
      INSERT INTO email_templates (key, subject, html, updated_by, updated_at)
      VALUES (${key}, ${parsed.data.subject}, ${parsed.data.html}, ${req.session.userId}, now())
      ON CONFLICT (key) DO UPDATE SET subject = EXCLUDED.subject, html = EXCLUDED.html, updated_by = EXCLUDED.updated_by, updated_at = now()
    `);
    return NextResponse.json({ ok: true });
  })
);

export const DELETE = withErrorHandler(
  withAuth(async (req: AuthedRequest, ctx: RouteContext) => {
    requireAdmin(req);
    await initDatabase();
    const { key } = await ctx.params;
    await db.execute(sql`DELETE FROM email_templates WHERE key = ${key}`);
    return NextResponse.json({ ok: true });
  })
);
