import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { createAdminClient } from '@/lib/supabase/admin'
import {
  approveClaim, companyHasAdmin, denyClaim, isCompanySchemaMissing, logCompanyEvent,
} from '@/lib/data/companies'
import { emailDomain, websiteDomain } from '@/lib/domain/company'
import type { Company, CompanyClaim } from '@/types/db'

const schema = z.object({
  decision: z.enum(['approve', 'deny', 'report']),
  approver_name: z.string().trim().min(1).max(120),
  approver_email: z.string().trim().email().max(200),
})

/**
 * Decision on a corporate approval link (Task 90; article §18). Everything
 * is re-checked here — never trust the page: token exists, not expired, not
 * already decided, and no in-app admin exists (then only the admin decides).
 */
export async function POST(req: NextRequest, ctx: { params: Promise<{ token: string }> }) {
  const { token } = await ctx.params
  const parsed = schema.safeParse(await req.json().catch(() => ({})))
  if (!parsed.success) return NextResponse.json({ error: 'Name, email and a decision are required.' }, { status: 400 })
  const input = parsed.data
  const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? null

  const admin = createAdminClient()
  const { data: claimRow, error } = await admin
    .from('company_claims')
    .select('*')
    .eq('approval_token', token)
    .maybeSingle()
  if (isCompanySchemaMissing(error)) {
    return NextResponse.json({ error: 'Company verification needs database migration 0013.' }, { status: 503 })
  }
  const claim = (claimRow ?? null) as CompanyClaim | null
  if (!claim || new Date(claim.expires_at).getTime() < Date.now()) {
    return NextResponse.json({ error: 'This approval link is invalid or has expired.' }, { status: 404 })
  }
  if (claim.claim_status !== 'pending_corporate_approval') {
    return NextResponse.json({ error: 'This request has already been decided.' }, { status: 409 })
  }
  if (await companyHasAdmin(claim.company_id)) {
    return NextResponse.json(
      { error: 'This company has a Company Admin — approvals happen from their Company Access panel.' },
      { status: 403 },
    )
  }

  const { data: companyRow } = await admin.from('companies').select('*').eq('id', claim.company_id).maybeSingle()
  const company = (companyRow ?? null) as Company | null
  const approverLabel = `${input.approver_name} <${input.approver_email}>`

  if (input.decision === 'approve') {
    // §18 "suspicious approvals go to admin review": nobody on file at the
    // company and the approver's domain does not match the company's.
    const approverDomain = emailDomain(input.approver_email)
    const companyDomains = new Set(
      [emailDomain(company?.corporate_email), websiteDomain(company?.website)].filter(Boolean),
    )
    const suspicious = !company?.corporate_email && (!approverDomain || !companyDomains.has(approverDomain))
    if (suspicious) {
      const now = new Date().toISOString()
      await admin
        .from('company_claims')
        .update({
          claim_status: 'admin_review_required',
          review_reason: 'suspicious_approval',
          approver_name: input.approver_name,
          approver_email: input.approver_email,
          approver_ip: ip,
          updated_at: now,
        })
        .eq('id', claim.id)
      await logCompanyEvent({
        companyId: claim.company_id,
        actorLabel: approverLabel,
        eventType: 'claim_flagged',
        newValue: { claim_id: claim.id, reason: 'suspicious_approval' },
        ip,
      })
      return NextResponse.json({ ok: true, status: 'admin_review_required' })
    }
    const result = await approveClaim({
      claim,
      approverLabel: input.approver_name,
      approverEmail: input.approver_email,
      ip,
      via: 'corporate_email',
    })
    if (!result.ok) return NextResponse.json({ error: result.error }, { status: 400 })
    return NextResponse.json({ ok: true, status: 'approved', role: result.role })
  }

  await denyClaim({
    claim,
    approverLabel: input.approver_name,
    approverEmail: input.approver_email,
    ip,
    reported: input.decision === 'report',
  })
  return NextResponse.json({ ok: true, status: input.decision === 'report' ? 'admin_review_required' : 'rejected' })
}
