import { NextResponse } from 'next/server';
import { z } from 'zod';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { errorResponse, ValidationError } from '@/lib/errors';
import { parseBody } from '@/lib/api/route-helpers';
import { getPortBrandingConfig } from '@/lib/services/port-config';
import { renderShell } from '@/lib/email/shell';
import { sendEmail } from '@/lib/email';

const SAMPLE_SUBJECT_SUFFIX = ' — branding preview';

function buildSampleEmail(branding: {
  logoUrl: string | null;
  emailBackgroundUrl: string | null;
  primaryColor: string;
  appName: string;
  emailHeaderHtml: string | null;
  emailFooterHtml: string | null;
}): { subject: string; html: string } {
  const subject = `${branding.appName}${SAMPLE_SUBJECT_SUFFIX}`;
  const body = `
    <h1 style="font-size:20px;margin:0 0 12px;color:${branding.primaryColor};">A sample notification</h1>
    <p style="margin:0 0 12px;color:#334155;">Hi there,</p>
    <p style="margin:0 0 12px;color:#334155;">
      This is a preview of how transactional emails from <strong>${branding.appName}</strong>
      will look using the current branding settings (logo, background image, primary color,
      and any custom header/footer HTML you've added).
    </p>
    <p style="margin:0 0 12px;">
      <a href="https://example.com" style="display:inline-block;padding:10px 18px;background-color:${branding.primaryColor};color:#ffffff;text-decoration:none;border-radius:6px;font-weight:600;">
        Primary action button
      </a>
    </p>
    <p style="margin:0;color:#64748b;font-size:13px;">
      Adjust the values in the Identity and Email branding cards above, save, then refresh the
      preview to see your changes.
    </p>
  `;
  const html = renderShell({
    title: subject,
    body,
    branding: {
      logoUrl: branding.logoUrl,
      backgroundUrl: branding.emailBackgroundUrl,
      primaryColor: branding.primaryColor,
      emailHeaderHtml: branding.emailHeaderHtml,
      emailFooterHtml: branding.emailFooterHtml,
    },
  });
  return { subject, html };
}

// GET — return the sample email rendered with the current port's branding.
export const GET = withAuth(
  withPermission('admin', 'manage_settings', async (_req, ctx) => {
    try {
      if (!ctx.portId) throw new ValidationError('No active port');
      const branding = await getPortBrandingConfig(ctx.portId);
      const { subject, html } = buildSampleEmail(branding);
      return NextResponse.json({ data: { subject, html } });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);

const sendTestSchema = z.object({
  recipient: z.string().email('Enter a valid email address'),
});

// POST — actually send the sample email to a single recipient.
export const POST = withAuth(
  withPermission('admin', 'manage_settings', async (req, ctx) => {
    try {
      if (!ctx.portId) throw new ValidationError('No active port');
      const { recipient } = await parseBody(req, sendTestSchema);
      const branding = await getPortBrandingConfig(ctx.portId);
      const { subject, html } = buildSampleEmail(branding);
      await sendEmail(recipient, subject, html);
      return NextResponse.json({ data: { sent: true, recipient } });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
