import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { createAdminClient } from '@/lib/supabase/admin'
import { publicOrigin } from '@/lib/app-url'
import { sendEmail } from '@/lib/adapters/email'
import { hasUnresolvedVariables } from '@/lib/domain/pilot-network'
import { loadPilotTemplates, loadProfile, logPilotNetworkAction, pilotNetworkAvailable, renderForProfile } from '@/lib/data/pilot-network'
import { migrationMissing, requireInternal } from '../_guard'

/**
 * Pilot Invitation Email Templates (§14–§15): create, edit subject / body /
 * CTA / footer / unsubscribe wording, activate / deactivate, preview with a
 * real lead, send a test email (recorded, answer 1). Every save writes a
 * version row (existing behaviour of email_template_versions).
 */

const saveSchema = z.object({
  action: z.literal('save'),
  key: z.string().trim().regex(/^[a-z0-9_]{3,80}$/, 'lowercase letters, digits and underscores'),
  name: z.string().trim().min(1).max(160),
  subject: z.string().trim().min(1).max(300),
  body: z.string().trim().min(1).max(20_000),
  cta_text: z.string().trim().max(80),
  footer: z.string().trim().max(2000),
  unsubscribe_text: z.string().trim().max(1000),
  active: z.boolean(),
  reason: z.string().trim().max(300).optional(),
})
const previewSchema = z.object({ action: z.enum(['preview', 'test']), key: z.string().trim().max(80), profile_id: z.string().uuid().optional(), to: z.string().trim().email().optional() })

export async function POST(req: NextRequest) {
  const guard = await requireInternal()
  if (!guard.ok) return guard.response
  const body = await req.json().catch(() => ({}))
  const admin = createAdminClient()
  if (!(await pilotNetworkAvailable(admin))) return migrationMissing()
  const { actor } = guard

  if (body?.action === 'save') {
    const parsed = saveSchema.safeParse(body)
    if (!parsed.success) return NextResponse.json({ error: parsed.error.issues[0]?.message ?? 'Invalid template.' }, { status: 400 })
    const t = parsed.data
    const { data: tpl, error } = await admin
      .from('email_templates')
      .upsert(
        {
          key: t.key,
          name: t.name,
          subject: t.subject,
          body: t.body,
          cta_text: t.cta_text || null,
          footer: t.footer || null,
          unsubscribe_text: t.unsubscribe_text || null,
          active: t.active,
          category: 'pilot_invitation',
          recipients_note: 'The pilot lead',
          trigger_note: 'Pilot invitation campaigns',
          updated_by: actor.label,
          updated_at: new Date().toISOString(),
        },
        { onConflict: 'key' },
      )
      .select('id, category')
      .single()
    if (error || !tpl) return NextResponse.json({ error: 'Could not save the template.' }, { status: 500 })
    if (tpl.category !== 'pilot_invitation') return NextResponse.json({ error: 'That key belongs to a system template.' }, { status: 409 })
    await admin.from('email_template_versions').insert({ template_id: tpl.id, subject: t.subject, body: t.body, edited_by: actor.label, reason: t.reason || null })
    await logPilotNetworkAction({ actorId: actor.id, actorLabel: actor.label, action: 'template_changed', entityType: 'template', entityId: t.key, detail: { active: t.active, reason: t.reason ?? null } }, admin)
    return NextResponse.json({ ok: true })
  }

  const parsed = previewSchema.safeParse(body)
  if (!parsed.success) return NextResponse.json({ error: 'Invalid request.' }, { status: 400 })
  const templates = await loadPilotTemplates(admin)
  const template = templates.find((x) => x.key === parsed.data.key)
  if (!template) return NextResponse.json({ error: 'Template not found.' }, { status: 404 })
  const profile = parsed.data.profile_id ? await loadProfile(parsed.data.profile_id, admin) : null
  const rendered = profile
    ? await renderForProfile(template, profile, publicOrigin(req), admin)
    : await renderForProfile(
        template,
        {
          id: 'sample', name: 'Sample Pilot', company_name: null, email: 'pilot@example.com', phone: null, primary_state: 'AK', related_states: ['AK'],
          account_type: 'unknown', claim_status: 'unclaimed', invitation_status: 'imported', email_opt_in_status: 'not_opted_in', sms_opt_in_status: 'not_opted_in',
          source: 'sample', source_reference: null, last_contacted_at: null, next_follow_up_at: null, claimed_user_id: null, claimed_company_id: null, claimed_at: null,
          admin_notes: null, claim_token: 'sampletokensampletokensampletokensampletoken0000', unsubscribe_token: 'sampletokensampletokensampletokensampletoken0001', created_at: '', updated_at: '',
          capabilities: [{ capability_type_id: 'x', key: 'lead', label: 'Lead', group: 'position', data_status: 'imported' }],
        },
        publicOrigin(req),
        admin,
      )
  const unresolved = hasUnresolvedVariables(rendered.subject) || hasUnresolvedVariables(rendered.text)
  if (parsed.data.action === 'preview') return NextResponse.json({ ok: true, ...rendered, unresolved })

  if (!parsed.data.to) return NextResponse.json({ error: 'Enter an address for the test email.' }, { status: 400 })
  const result = await sendEmail({ to: parsed.data.to, subject: `[TEST] ${rendered.subject}`, text: rendered.text, stream: 'updates', tags: { kind: 'test', template: template.key } })
  if (result.status === 'failed') {
    await logPilotNetworkAction({ actorId: actor.id, actorLabel: actor.label, action: 'test_email_failed', entityType: 'template', entityId: template.key, detail: { to: parsed.data.to, error: result.error } }, admin)
    return NextResponse.json({ error: `ZeptoMail refused the test email: ${result.error}` }, { status: 502 })
  }
  if (profile) {
    await admin.from('pilot_invitation_events').insert({ profile_id: profile.id, template_id: template.id, template_key: template.key, kind: 'test_sent', email_status: result.status, rendered_subject: rendered.subject, detail: { to: parsed.data.to } })
  }
  await logPilotNetworkAction({ actorId: actor.id, actorLabel: actor.label, action: result.status === 'sent' ? 'test_email_sent' : 'test_email_recorded', entityType: 'template', entityId: template.key, detail: { to: parsed.data.to, email_status: result.status, message_id: result.message_id } }, admin)
  return NextResponse.json({ ok: true, status: result.status })
}
