import React, { useState } from 'react';
import { Button } from '@/components/ui/button';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
import { FileText, Download, Loader2 } from 'lucide-react';
import { format } from 'date-fns';
import jsPDF from 'jspdf';
import autoTable from 'jspdf-autotable';
import { useToast } from '@/hooks/use-toast';

export default function ElectionReportGenerator({ election, positions, candidates, voters, results }) {
  const [generating, setGenerating] = useState(false);
  const { toast } = useToast();

  const resultsByPosition = {};
  positions.forEach(p => { resultsByPosition[p.id] = {}; });
  results.forEach(b => {
    if (!resultsByPosition[b.position_id]) resultsByPosition[b.position_id] = {};
    resultsByPosition[b.position_id][b.candidate_id] = (resultsByPosition[b.position_id][b.candidate_id] || 0) + 1;
  });

  const votedCount = voters.filter(v => v.has_voted).length;
  const consentCount = voters.filter(v => v.has_consent).length;
  const totalParticipation = votedCount + (election.proxies_count || 0) + (election.in_person_count || 0);

  const generatePDF = async () => {
    setGenerating(true);
    try {
      const doc = new jsPDF();
      const pageW = doc.internal.pageSize.getWidth();
      let y = 20;

      // Title
      doc.setFontSize(18);
      doc.setFont('helvetica', 'bold');
      doc.text('CERTIFIED ELECTION REPORT', pageW / 2, y, { align: 'center' });
      y += 10;

      doc.setFontSize(10);
      doc.setFont('helvetica', 'normal');
      doc.text('Compliant with Florida Statutes §718 / §720', pageW / 2, y, { align: 'center' });
      y += 15;

      // Election info
      doc.setFontSize(12);
      doc.setFont('helvetica', 'bold');
      doc.text(election.title, 14, y);
      y += 7;

      doc.setFontSize(9);
      doc.setFont('helvetica', 'normal');
      const infoLines = [
        `Association: ${election.association?.name || 'N/A'}`,
        `Type: ${election.election_type?.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase()) || 'N/A'}`,
        `Status: ${election.status?.toUpperCase()}`,
        `Voting Period: ${election.voting_start ? format(new Date(election.voting_start), 'MMM d, yyyy h:mm a') : 'N/A'} — ${election.voting_end ? format(new Date(election.voting_end), 'MMM d, yyyy h:mm a') : 'N/A'}`,
        `Report Generated: ${format(new Date(), 'MMM d, yyyy h:mm a')}`,
      ];
      infoLines.forEach(line => { doc.text(line, 14, y); y += 5; });
      y += 5;

      // Quorum summary
      doc.setFontSize(11);
      doc.setFont('helvetica', 'bold');
      doc.text('PARTICIPATION & QUORUM', 14, y);
      y += 7;

      autoTable(doc, {
        startY: y,
        head: [['Metric', 'Count']],
        body: [
          ['Total Eligible Voters', String(voters.length)],
          ['Electronic Consents', String(consentCount)],
          ['Online Votes Cast', String(votedCount)],
          ['Proxies', String(election.proxies_count || 0)],
          ['In-Person', String(election.in_person_count || 0)],
          ['Total Participation', String(totalParticipation)],
          ['Quorum Required', election.quorum_required > 0 ? String(election.quorum_required) : 'N/A'],
          ['Quorum Met', election.quorum_required > 0 ? (totalParticipation >= election.quorum_required ? 'YES ✓' : 'NO') : 'N/A'],
        ],
        theme: 'grid',
        headStyles: { fillColor: [41, 65, 148], fontSize: 9 },
        bodyStyles: { fontSize: 9 },
        columnStyles: { 0: { fontStyle: 'bold' } },
        margin: { left: 14, right: 14 },
      });
      y = doc.lastAutoTable.finalY + 10;

      // Results per position
      if (election.results_locked) {
        doc.setFontSize(11);
        doc.setFont('helvetica', 'bold');
        doc.text('ELECTION RESULTS', 14, y);
        y += 7;

        positions.forEach(pos => {
          const posCandidates = candidates.filter(c => c.position_id === pos.id);
          const posResults = resultsByPosition[pos.id] || {};
          const totalPosVotes = Object.values(posResults).reduce((a, b) => a + b, 0);

          const body = posCandidates.map(c => {
            const count = posResults[c.id] || 0;
            const pct = totalPosVotes > 0 ? Math.round((count / totalPosVotes) * 100) : 0;
            return [c.candidate_name, String(count), `${pct}%`];
          });

          if (y > 250) { doc.addPage(); y = 20; }

          autoTable(doc, {
            startY: y,
            head: [[`${pos.title} (${pos.seats_available} seat${pos.seats_available > 1 ? 's' : ''})`, 'Votes', '%']],
            body,
            theme: 'grid',
            headStyles: { fillColor: [41, 65, 148], fontSize: 9 },
            bodyStyles: { fontSize: 9 },
            margin: { left: 14, right: 14 },
          });
          y = doc.lastAutoTable.finalY + 8;
        });
      } else {
        doc.setFontSize(10);
        doc.text('Results have not been certified yet — tallies not included in this report.', 14, y);
        y += 10;
      }

      // Certification footer
      if (y > 240) { doc.addPage(); y = 20; }
      y += 10;
      doc.setDrawColor(41, 65, 148);
      doc.setLineWidth(0.5);
      doc.line(14, y, pageW - 14, y);
      y += 8;
      doc.setFontSize(10);
      doc.setFont('helvetica', 'bold');
      doc.text('CERTIFICATION', 14, y);
      y += 6;
      doc.setFont('helvetica', 'normal');
      doc.setFontSize(8);
      const certText = [
        'This report is generated from the electronic election system. All votes were cast via secret ballot.',
        'Voter identities are tracked separately from ballot selections to ensure anonymity per FL §718.112 / §720.306.',
        'An audit trail exists recording participation without revealing individual vote choices.',
        '',
        `Verification Hash: ${generateHash(election, voters, results)}`,
      ];
      certText.forEach(line => { doc.text(line, 14, y); y += 4.5; });

      // Signature lines
      y += 10;
      doc.setLineWidth(0.3);
      doc.line(14, y, 90, y);
      doc.line(pageW / 2 + 10, y, pageW - 14, y);
      y += 5;
      doc.setFontSize(8);
      doc.text('Election Inspector Signature', 14, y);
      doc.text('Date', pageW / 2 + 10, y);

      const fileName = `Election_Report_${election.title.replace(/\s+/g, '_')}_${format(new Date(), 'yyyy-MM-dd')}.pdf`;
      doc.save(fileName);
      toast({ title: 'Report Downloaded', description: `${fileName}` });
    } catch (err) {
      console.error('PDF generation error:', err);
      toast({ variant: 'destructive', title: 'Error', description: 'Failed to generate PDF report.' });
    } finally {
      setGenerating(false);
    }
  };

  const generateCSV = async () => {
    try {
      // Participation CSV
      const participationRows = [
        ['Election Report', election.title],
        ['Association', election.association?.name || ''],
        ['Generated', format(new Date(), 'yyyy-MM-dd HH:mm')],
        [''],
        ['PARTICIPATION'],
        ['Metric', 'Count'],
        ['Eligible Voters', voters.length],
        ['Consented', consentCount],
        ['Online Votes', votedCount],
        ['Proxies', election.proxies_count || 0],
        ['In-Person', election.in_person_count || 0],
        ['Total', totalParticipation],
        ['Quorum Required', election.quorum_required || 'N/A'],
        ['Quorum Met', election.quorum_required > 0 ? (totalParticipation >= election.quorum_required ? 'Yes' : 'No') : 'N/A'],
        [''],
      ];

      // Results
      if (election.results_locked) {
        participationRows.push(['RESULTS']);
        positions.forEach(pos => {
          const posCandidates = candidates.filter(c => c.position_id === pos.id);
          const posResults = resultsByPosition[pos.id] || {};
          const totalPosVotes = Object.values(posResults).reduce((a, b) => a + b, 0);
          participationRows.push([`Position: ${pos.title}`]);
          participationRows.push(['Candidate', 'Votes', 'Percentage']);
          posCandidates.forEach(c => {
            const count = posResults[c.id] || 0;
            const pct = totalPosVotes > 0 ? Math.round((count / totalPosVotes) * 100) : 0;
            participationRows.push([c.candidate_name, count, `${pct}%`]);
          });
          participationRows.push(['']);
        });
      }

      // Voter roster (no vote choices)
      participationRows.push(['VOTER ROSTER (Audit)']);
      participationRows.push(['Owner', 'Unit', 'Consented', 'Voted', 'Voted At']);
      voters.forEach(v => {
        participationRows.push([
          `${v.owner?.first_name || ''} ${v.owner?.last_name || ''}`.trim(),
          v.unit?.unit_number || v.unit?.address || '',
          v.has_consent ? 'Yes' : 'No',
          v.has_voted ? 'Yes' : 'No',
          v.voted_at ? format(new Date(v.voted_at), 'yyyy-MM-dd HH:mm') : '',
        ]);
      });

      const csvContent = participationRows.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(',')).join('\n');
      const { saveCsv } = await import('@/lib/saveFile');
      await saveCsv(csvContent, `Election_Report_${election.title.replace(/\s+/g, '_')}_${format(new Date(), 'yyyy-MM-dd')}.csv`);
      toast({ title: 'CSV Downloaded' });
    } catch (err) {
      console.error('CSV generation error:', err);
      toast({ variant: 'destructive', title: 'Error', description: 'Failed to generate CSV.' });
    }
  };

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline" size="sm" className="gap-2" disabled={generating}>
          {generating ? <Loader2 className="w-3 h-3 animate-spin" /> : <Download className="w-3 h-3" />}
          Export Report
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem onClick={generatePDF} className="gap-2">
          <FileText className="w-4 h-4" /> Certified PDF Report
        </DropdownMenuItem>
        <DropdownMenuItem onClick={generateCSV} className="gap-2">
          <Download className="w-4 h-4" /> CSV Export
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

function generateHash(election, voters, results) {
  const data = `${election.id}-${voters.length}-${results.length}-${Date.now()}`;
  let hash = 0;
  for (let i = 0; i < data.length; i++) {
    const char = data.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash |= 0;
  }
  return Math.abs(hash).toString(16).toUpperCase().padStart(8, '0');
}
