import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { createAdminClient } from '@/lib/supabase/admin'
import { publicOrigin } from '@/lib/app-url'
import { SEND_BLOCK_LABELS } from '@/lib/domain/pilot-network'
import { loadCampaigns, loadPilotTemplates, loadProfiles, logPilotNetworkAction, pilotNetworkAvailable, previewCampaignRecipients, runPilotCampaignsDay } from '@/lib/data/pilot-network'
import { migrationMissing, requireInternal } from '../_guard'

/**
 * Campaign management (§17–§19): create (state, contacts, templates, daily
 * limit, start date, follow-up delay), preview recipients, start / pause /
 * resume / stop, run today's batch. Audited (§26).
 */

const createSchema = z.object({
  action: z.literal('create'),
  name: z.string().trim().min(1).max(160),
  state: z.string().trim().length(2),
  template_key: z.string().trim().min(1).max(80),
  follow_up_template_key: z.string().trim().max(80).nullable(),
  daily_send_limit: z.number().int().min(1).max(5000),
  follow_up_delay_days: z.number().int().min(0).max(365),
  start_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  /** Explicit picks, or every Approved for Invitation lead in the state when empty. */
  profile_ids: z.array(z.string().uuid()).max(5000),
})
const transitionSchema = z.object({ action: z.enum(['start', 'pause', 'resume', 'stop', 'preview', 'run_today', 'update_limit']), id: z.string().uuid().optional(), daily_send_limit: z.number().int().min(1).max(5000).optional() })

const NEXT: Record<'start' | 'pause' | 'resume' | 'stop', { from: string[]; to: string }> = {
  start: { from: ['draft'], to: 'running' },
  pause: { from: ['running'], to: 'paused' },
  resume: { from: ['paused'], to: 'running' },
  stop: { from: ['draft', 'running', 'paused'], to: 'stopped' },
}

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
  const now = new Date().toISOString()

  if (body?.action === 'create') {
    const parsed = createSchema.safeParse(body)
    if (!parsed.success) return NextResponse.json({ error: parsed.error.issues[0]?.message ?? 'Invalid campaign.' }, { status: 400 })
    const c = parsed.data
    const templates = await loadPilotTemplates(admin)
    if (!templates.some((t) => t.key === c.template_key && t.active)) return NextResponse.json({ error: 'Choose an active initial template.' }, { status: 400 })
    if (c.follow_up_template_key && !templates.some((t) => t.key === c.follow_up_template_key && t.active)) return NextResponse.json({ error: 'Choose an active follow-up template.' }, { status: 400 })
    let ids = c.profile_ids
    if (ids.length === 0) {
      const { profiles } = await loadProfiles({ state: c.state.toUpperCase(), status: 'approved_for_invitation', pageSize: 200, page: 1 }, admin)
      ids = profiles.map((p) => p.id)
    }
    if (ids.length === 0) return NextResponse.json({ error: 'No contacts selected — approve leads in this state first, or pick contacts.' }, { status: 400 })
    const { data: campaign, error } = await admin
      .from('pilot_campaigns')
      .insert({ name: c.name, state: c.state.toUpperCase(), template_key: c.template_key, follow_up_template_key: c.follow_up_template_key, daily_send_limit: c.daily_send_limit, follow_up_delay_days: c.follow_up_delay_days, start_date: c.start_date, created_by: actor.label })
      .select('id')
      .single()
    if (error || !campaign) return NextResponse.json({ error: 'Could not create the campaign.' }, { status: 500 })
    await admin.from('pilot_campaign_recipients').insert(ids.map((profile_id) => ({ campaign_id: campaign.id, profile_id })))
    await logPilotNetworkAction({ actorId: actor.id, actorLabel: actor.label, action: 'campaign_created', entityType: 'campaign', entityId: campaign.id, detail: { name: c.name, state: c.state, recipients: ids.length, daily_send_limit: c.daily_send_limit, follow_up_delay_days: c.follow_up_delay_days } }, admin)
    return NextResponse.json({ ok: true, id: campaign.id })
  }

  const parsed = transitionSchema.safeParse(body)
  if (!parsed.success) return NextResponse.json({ error: 'Invalid request.' }, { status: 400 })
  const { action, id } = parsed.data

  if (action === 'run_today') {
    const summary = await runPilotCampaignsDay({ origin: publicOrigin(req), actorId: actor.id, actorLabel: actor.label, manual: true }, admin)
    return NextResponse.json({ ok: true, summary })
  }
  if (!id) return NextResponse.json({ error: 'Campaign id required.' }, { status: 400 })
  const campaign = (await loadCampaigns(admin)).find((c) => c.id === id)
  if (!campaign) return NextResponse.json({ error: 'Campaign not found.' }, { status: 404 })

  if (action === 'preview') {
    const recipients = await previewCampaignRecipients(id, admin)
    return NextResponse.json({
      ok: true,
      recipients: recipients.map((r) => ({ id: r.profile.id, name: r.profile.name, company_name: r.profile.company_name, email: r.profile.email, status: r.status, block: r.block ? SEND_BLOCK_LABELS[r.block] : null })),
    })
  }
  if (action === 'update_limit') {
    if (!parsed.data.daily_send_limit) return NextResponse.json({ error: 'Daily limit required.' }, { status: 400 })
    await admin.from('pilot_campaigns').update({ daily_send_limit: parsed.data.daily_send_limit, updated_at: now }).eq('id', id)
    await logPilotNetworkAction({ actorId: actor.id, actorLabel: actor.label, action: 'daily_limit_changed', entityType: 'campaign', entityId: id, detail: { from: campaign.daily_send_limit, to: parsed.data.daily_send_limit } }, admin)
    return NextResponse.json({ ok: true })
  }
  const rule = NEXT[action]
  if (!rule.from.includes(campaign.status)) return NextResponse.json({ error: `Cannot ${action} a ${campaign.status} campaign.` }, { status: 409 })
  await admin.from('pilot_campaigns').update({ status: rule.to, updated_at: now }).eq('id', id)
  await logPilotNetworkAction({ actorId: actor.id, actorLabel: actor.label, action: `campaign_${action === 'resume' ? 'resumed' : action === 'stop' ? 'stopped' : action === 'pause' ? 'paused' : 'started'}`, entityType: 'campaign', entityId: id, detail: { from: campaign.status, to: rule.to } }, admin)
  return NextResponse.json({ ok: true })
}
