'use client'

import { useState, useCallback, type RefObject } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import { FileDown, Loader2 } from 'lucide-react'
import { toast } from 'sonner'
import {
  createReportDocument,
  addCoverPage,
  addPageBreak,
  addHeader,
  addSectionTitle,
  addStatCards,
  addTable,
  addChartImage,
  addAllPageFooters,
  savePdf,
} from '@/lib/pdf-generator'

interface ExportPdfButtonProps {
  roundId: string
  roundName?: string
  programName?: string
  chartRefs?: Record<string, RefObject<HTMLDivElement | null>>
  variant?: 'default' | 'outline' | 'secondary' | 'ghost'
  size?: 'default' | 'sm' | 'lg' | 'icon'
}

export function ExportPdfButton({
  roundId,
  roundName,
  programName,
  chartRefs,
  variant = 'outline',
  size = 'sm',
}: ExportPdfButtonProps) {
  const [generating, setGenerating] = useState(false)

  const { refetch } = trpc.export.getReportData.useQuery(
    { roundId, sections: [] },
    { enabled: false }
  )

  const handleGenerate = useCallback(async () => {
    setGenerating(true)
    toast.info('Generating PDF report...')

    try {
      const result = await refetch()
      if (!result.data) {
        toast.error('Failed to fetch report data')
        return
      }

      const data = result.data as Record<string, unknown>
      const rName = roundName || String(data.roundName || 'Report')
      const pName = programName || String(data.programName || '')

      // 1. Create document
      const doc = await createReportDocument()

      // 2. Cover page
      await addCoverPage(doc, {
        title: 'Round Report',
        subtitle: `${pName} ${data.programYear ? `(${data.programYear})` : ''}`.trim(),
        roundName: rName,
        programName: pName,
      })

      // 3. Summary section
      const summary = data.summary as Record<string, unknown> | undefined
      if (summary) {
        addPageBreak(doc)
        await addHeader(doc, rName)
        let y = addSectionTitle(doc, 'Summary', 28)

        y = addStatCards(doc, [
          { label: 'Projects', value: String(summary.projectCount ?? 0) },
          { label: 'Evaluations', value: String(summary.evaluationCount ?? 0) },
          {
            label: 'Avg Score',
            value: summary.averageScore != null
              ? Number(summary.averageScore).toFixed(1)
              : '--',
          },
          {
            label: 'Completion',
            value: summary.completionRate != null
              ? `${Number(summary.completionRate).toFixed(0)}%`
              : '--',
          },
        ], y)

        // Capture chart images if refs provided
        if (chartRefs) {
          for (const [, ref] of Object.entries(chartRefs)) {
            if (ref.current) {
              try {
                y = await addChartImage(doc, ref.current, y, { maxHeight: 90 })
              } catch {
                // Skip chart if capture fails
              }
            }
          }
        }
      }

      // 4. Rankings section
      const rankings = data.rankings as Array<Record<string, unknown>> | undefined
      if (rankings && rankings.length > 0) {
        addPageBreak(doc)
        await addHeader(doc, rName)
        let y = addSectionTitle(doc, 'Project Rankings', 28)

        const headers = ['#', 'Project', 'Team', 'Avg Score', 'Evaluations', 'Yes %']
        const rows = rankings.map((r, i) => [
          i + 1,
          String(r.title ?? ''),
          String(r.teamName ?? ''),
          r.averageScore != null ? Number(r.averageScore).toFixed(2) : '-',
          String(r.evaluationCount ?? 0),
          r.yesPercentage != null ? `${Number(r.yesPercentage).toFixed(0)}%` : '-',
        ])

        y = addTable(doc, headers, rows, y)
      }

      // 5. Juror stats section
      const jurorStats = data.jurorStats as Array<Record<string, unknown>> | undefined
      if (jurorStats && jurorStats.length > 0) {
        addPageBreak(doc)
        await addHeader(doc, rName)
        let y = addSectionTitle(doc, 'Juror Statistics', 28)

        const headers = ['Juror', 'Assigned', 'Completed', 'Completion %', 'Avg Score']
        const rows = jurorStats.map((j) => [
          String(j.name ?? ''),
          String(j.assigned ?? 0),
          String(j.completed ?? 0),
          `${Number(j.completionRate ?? 0).toFixed(0)}%`,
          j.averageScore != null ? Number(j.averageScore).toFixed(2) : '-',
        ])

        y = addTable(doc, headers, rows, y)
      }

      // 6. Criteria breakdown
      const criteriaBreakdown = data.criteriaBreakdown as Array<Record<string, unknown>> | undefined
      if (criteriaBreakdown && criteriaBreakdown.length > 0) {
        addPageBreak(doc)
        await addHeader(doc, rName)
        let y = addSectionTitle(doc, 'Criteria Breakdown', 28)

        const headers = ['Criterion', 'Avg Score', 'Responses']
        const rows = criteriaBreakdown.map((c) => [
          String(c.label ?? ''),
          c.averageScore != null ? Number(c.averageScore).toFixed(2) : '-',
          String(c.count ?? 0),
        ])

        y = addTable(doc, headers, rows, y)
      }

      // 7. Footer on all pages
      addAllPageFooters(doc)

      // 8. Save
      const dateStr = new Date().toISOString().split('T')[0]
      savePdf(doc, `MOPC-Report-${rName.replace(/\s+/g, '-')}-${dateStr}.pdf`)

      toast.success('PDF report downloaded successfully')
    } catch (err) {
      console.error('PDF generation error:', err)
      toast.error('Failed to generate PDF report')
    } finally {
      setGenerating(false)
    }
  }, [refetch, roundName, programName, chartRefs])

  return (
    <Button variant={variant} size={size} onClick={handleGenerate} disabled={generating}>
      {generating ? (
        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
      ) : (
        <FileDown className="mr-2 h-4 w-4" />
      )}
      {generating ? 'Generating...' : 'Export PDF Report'}
    </Button>
  )
}
