import React, { useState, useEffect, useCallback } from 'react';
import { useToast } from '@/hooks/use-toast';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Progress } from '@/components/ui/progress';
import { Plus, Trash2, Users, Vote, Shield, BarChart3, Lock, Unlock, CheckCircle2, XCircle, Loader2, UserPlus, Send, Download } from 'lucide-react';
import { useElections } from '@/hooks/useElections';
import { supabase } from '@/integrations/supabase/client';
import { format } from 'date-fns';
import ElectionReportGenerator from './ElectionReportGenerator';
import ElectionNoticeGenerator from './ElectionNoticeGenerator';
import ElectionTallyCounter from './ElectionTallyCounter';
import { generateCertificationPDF } from './ElectionCertificationPDF';

export default function ElectionDetailDialog({ open, onOpenChange, election, onUpdate }) {
  const {
    fetchPositions, createPosition, deletePosition,
    fetchAllCandidates, createCandidate, deleteCandidate,
    fetchEligibleVoters, addEligibleVoters, updateVoterConsent,
    fetchResults, fetchAuditLog, updateElection, loading
  } = useElections();
  const { toast } = useToast();

  const [tab, setTab] = useState('positions');
  const [positions, setPositions] = useState([]);
  const [candidates, setCandidates] = useState([]);
  const [voters, setVoters] = useState([]);
  const [results, setResults] = useState([]);
  const [auditLog, setAuditLog] = useState([]);
  const [newPosition, setNewPosition] = useState('');
  const [newCandidate, setNewCandidate] = useState({ name: '', bio: '', positionId: '' });
  const [addingVoters, setAddingVoters] = useState(false);
  const [sendingInvites, setSendingInvites] = useState(false);

  const handleSendInvites = async () => {
    setSendingInvites(true);
    try {
      const baseUrl = window.location.origin;
      const { data, error } = await supabase.functions.invoke('send-election-invites', {
        body: { election_id: election.id, base_url: baseUrl }
      });
      if (error) throw error;
      const msg = `Sent ${data.sent} invite(s)${data.failed ? `, ${data.failed} failed` : ''}`;
      toast({ title: 'Invites Sent', description: msg });
      loadData();
    } catch (err) {
      console.error(err);
      toast({ variant: 'destructive', title: 'Error', description: 'Failed to send invites.' });
    } finally {
      setSendingInvites(false);
    }
  };

  const loadData = useCallback(async () => {
    if (!election?.id) return;
    const [pos, cands, vot] = await Promise.all([
      fetchPositions(election.id),
      fetchAllCandidates(election.id),
      fetchEligibleVoters(election.id),
    ]);
    setPositions(pos);
    setCandidates(cands);
    setVoters(vot);
  }, [election?.id, fetchPositions, fetchAllCandidates, fetchEligibleVoters]);

  useEffect(() => {
    if (open && election?.id) loadData();
  }, [open, election?.id, loadData]);

  useEffect(() => {
    if (tab === 'results' && election?.id) {
      fetchResults(election.id).then(setResults);
    }
  }, [tab, election?.id, fetchResults]);

  const handleAddPosition = async () => {
    if (!newPosition.trim()) return;
    await createPosition({ election_id: election.id, title: newPosition.trim(), sort_order: positions.length });
    setNewPosition('');
    loadData();
  };

  const handleAddCandidate = async () => {
    if (!newCandidate.name.trim() || !newCandidate.positionId) return;
    await createCandidate({
      position_id: newCandidate.positionId,
      candidate_name: newCandidate.name.trim(),
      bio: newCandidate.bio || null,
      sort_order: candidates.filter(c => c.position_id === newCandidate.positionId).length
    });
    setNewCandidate({ name: '', bio: '', positionId: '' });
    loadData();
  };

  const handleAutoPopulateVoters = async () => {
    setAddingVoters(true);
    try {
      const { data: owners } = await supabase
        .from('owners')
        .select('id, unit_id')
        .eq('association_id', election.association_id)
        .eq('status', 'active');

      if (!owners?.length) return;

      // Deduplicate by unit - one vote per unit
      const unitMap = new Map();
      owners.forEach(o => {
        if (o.unit_id && !unitMap.has(o.unit_id)) {
          unitMap.set(o.unit_id, o);
        }
      });

      const existingUnits = new Set(voters.map(v => v.unit_id));
      const newVoters = Array.from(unitMap.values())
        .filter(o => !existingUnits.has(o.unit_id))
        .map(o => ({
          election_id: election.id,
          owner_id: o.id,
          unit_id: o.unit_id,
        }));

      if (newVoters.length > 0) {
        await addEligibleVoters(newVoters);
        loadData();
      }
    } finally {
      setAddingVoters(false);
    }
  };

  const handleToggleConsent = async (voterId, current) => {
    await updateVoterConsent(voterId, !current);
    loadData();
  };

  const handleToggleResultsLock = async () => {
    await updateElection(election.id, { results_locked: !election.results_locked });
    onUpdate();
  };

  const totalVoters = voters.length;
  const votedCount = voters.filter(v => v.has_voted).length;
  const consentCount = voters.filter(v => v.has_consent).length;
  const quorumMet = election.quorum_required > 0
    ? (votedCount + (election.proxies_count || 0) + (election.in_person_count || 0)) >= election.quorum_required
    : true;
  const totalParticipation = votedCount + (election.proxies_count || 0) + (election.in_person_count || 0);

  // Tally results by position
  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;
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="w-[min(96vw,1100px)] max-w-none max-h-[92vh] flex flex-col overflow-hidden p-4 sm:p-6">
        <DialogHeader className="gap-3 pr-8">
          <DialogTitle className="flex flex-wrap items-center gap-3 pr-8 leading-snug">
            {election.title}
            <Badge variant={election.status === 'active' ? 'default' : 'secondary'}>
              {election.status}
            </Badge>
          </DialogTitle>
          <DialogDescription className="sr-only">
            Election details, voter participation, tally tools, and certified report exports.
          </DialogDescription>
          <div className="flex flex-wrap gap-2 pr-8">
            {election.status === 'active' && (
              <Button variant="outline" size="sm" className="gap-1 text-xs" onClick={handleSendInvites} disabled={sendingInvites}>
                {sendingInvites ? <Loader2 className="w-3 h-3 animate-spin" /> : <Send className="w-3 h-3" />}
                Send Voting Links
              </Button>
            )}
            <ElectionNoticeGenerator
              election={election}
              positions={positions}
              candidates={candidates}
              voters={voters}
            />
            <ElectionReportGenerator
              election={election}
              positions={positions}
              candidates={candidates}
              voters={voters}
              results={results}
            />
          </div>
        </DialogHeader>

        <div className="flex-1 min-h-0 overflow-y-auto space-y-3 pr-1">
        {/* Quick stats bar */}
        <div className="grid grid-cols-2 gap-3 py-2 lg:grid-cols-4">
          <div className="text-center p-2 bg-muted rounded-lg">
            <div className="text-2xl font-bold text-foreground">{totalVoters}</div>
            <div className="text-xs text-muted-foreground">Eligible</div>
          </div>
          <div className="text-center p-2 bg-muted rounded-lg">
            <div className="text-2xl font-bold text-foreground">{consentCount}</div>
            <div className="text-xs text-muted-foreground">Consented</div>
          </div>
          <div className="text-center p-2 bg-muted rounded-lg">
            <div className="text-2xl font-bold text-primary">{totalParticipation}</div>
            <div className="text-xs text-muted-foreground">Participated</div>
          </div>
          <div className="text-center p-2 rounded-lg" style={{ background: quorumMet ? 'hsl(var(--primary) / 0.1)' : 'hsl(var(--destructive) / 0.1)' }}>
            <div className={`text-2xl font-bold ${quorumMet ? 'text-primary' : 'text-destructive'}`}>
              {quorumMet ? '✓' : '✗'}
            </div>
            <div className="text-xs text-muted-foreground">Quorum {election.quorum_required > 0 ? `(${election.quorum_required})` : '(N/A)'}</div>
          </div>
        </div>

        {totalVoters > 0 && (
          <div className="space-y-1">
            <div className="flex justify-between text-xs text-muted-foreground">
              <span>Participation: {votedCount}/{totalVoters} online votes</span>
              <span>{totalVoters > 0 ? Math.round((votedCount / totalVoters) * 100) : 0}%</span>
            </div>
            <Progress value={totalVoters > 0 ? (votedCount / totalVoters) * 100 : 0} className="h-2" />
          </div>
        )}

          <Tabs value={tab} onValueChange={setTab}>
          <TabsList className="grid h-auto w-full grid-cols-2 gap-1 sm:grid-cols-5">
            <TabsTrigger value="tally" className="text-xs">Tally</TabsTrigger>
            <TabsTrigger value="positions" className="text-xs">Positions</TabsTrigger>
            <TabsTrigger value="voters" className="text-xs">Voters</TabsTrigger>
            <TabsTrigger value="quorum" className="text-xs">Quorum</TabsTrigger>
            <TabsTrigger value="results" className="text-xs">Results</TabsTrigger>
          </TabsList>

          {/* TALLY TAB */}
          <TabsContent value="tally">
            <ScrollArea className="h-[350px] pr-3">
              {election.status !== 'closed' ? (
                <div className="text-center py-12 text-muted-foreground text-sm">
                  <p>Close voting before tallying in-person ballots.</p>
                </div>
              ) : positions.length === 0 || candidates.length === 0 ? (
                <div className="text-center py-12 text-muted-foreground text-sm">
                  <p>Add positions and candidates first.</p>
                </div>
              ) : (
                <ElectionTallyCounter
                  election={election}
                  positions={positions}
                  candidates={candidates}
                  onCertify={async (tallies) => {
                    try {
                      console.log('Starting certification with tallies:', tallies);
                      // Lock results
                      const lockResult = await updateElection(election.id, { results_locked: true, status: 'closed' });
                      console.log('Lock result:', lockResult);
                      if (!lockResult) {
                        toast({ variant: 'destructive', title: 'Error', description: 'Failed to lock election results. Check permissions.' });
                        return;
                      }
                      // Generate certification PDF
                      console.log('Generating PDF...');
                      const fileName = generateCertificationPDF({
                        election,
                        positions,
                        candidates,
                        voters,
                        tallies,
                      });
                      console.log('PDF generated:', fileName);
                      toast({ title: 'Election Certified', description: `Results locked and certification downloaded: ${fileName}` });
                      onUpdate();
                    } catch (err) {
                      console.error('Certification error:', err);
                      console.error('Error stack:', err?.stack);
                      toast({ variant: 'destructive', title: 'Error', description: err?.message || 'Failed to certify election.' });
                    }
                  }}
                />
              )}
            </ScrollArea>
          </TabsContent>

          {/* POSITIONS & CANDIDATES TAB */}
          <TabsContent value="positions">
            <ScrollArea className="h-[350px] pr-3">
              <div className="space-y-4">
                {election.status === 'draft' && (
                  <div className="flex gap-2">
                    <Input value={newPosition} onChange={e => setNewPosition(e.target.value)} placeholder="Position title (e.g. President)" className="flex-1" onKeyDown={e => e.key === 'Enter' && (e.preventDefault(), handleAddPosition())} />
                    <Button onClick={handleAddPosition} size="sm" className="gap-1"><Plus className="w-3 h-3" /> Add Position</Button>
                  </div>
                )}

                {positions.map(pos => {
                  const posCandidates = candidates.filter(c => c.position_id === pos.id);
                  return (
                    <Card key={pos.id}>
                      <CardHeader className="pb-2 pt-3 px-4">
                        <div className="flex items-center justify-between">
                          <CardTitle className="text-sm font-semibold">{pos.title}</CardTitle>
                          <div className="flex items-center gap-2">
                            <span className="text-xs text-muted-foreground">{pos.seats_available} seat(s)</span>
                            {election.status === 'draft' && (
                              <Button variant="ghost" size="icon" className="h-6 w-6" onClick={async () => { await deletePosition(pos.id); loadData(); }}>
                                <Trash2 className="w-3 h-3 text-muted-foreground hover:text-destructive" />
                              </Button>
                            )}
                          </div>
                        </div>
                      </CardHeader>
                      <CardContent className="px-4 pb-3 space-y-2">
                        {posCandidates.map(c => (
                          <div key={c.id} className="flex items-center justify-between px-3 py-2 bg-muted/50 rounded-md">
                            <div>
                              <p className="text-sm font-medium">{c.candidate_name}</p>
                              {c.bio && <p className="text-xs text-muted-foreground">{c.bio}</p>}
                            </div>
                            {election.status === 'draft' && (
                              <Button variant="ghost" size="icon" className="h-6 w-6" onClick={async () => { await deleteCandidate(c.id); loadData(); }}>
                                <Trash2 className="w-3 h-3 text-muted-foreground hover:text-destructive" />
                              </Button>
                            )}
                          </div>
                        ))}
                        {election.status === 'draft' && (
                          <div className="flex gap-2 pt-1">
                            <Input
                              placeholder="Candidate name"
                              value={newCandidate.positionId === pos.id ? newCandidate.name : ''}
                              onChange={e => setNewCandidate({ name: e.target.value, bio: newCandidate.positionId === pos.id ? newCandidate.bio : '', positionId: pos.id })}
                              className="flex-1 h-8 text-sm"
                              onKeyDown={e => {
                                if (e.key === 'Enter') {
                                  e.preventDefault();
                                  if (newCandidate.positionId === pos.id && newCandidate.name.trim()) {
                                    handleAddCandidate();
                                  }
                                }
                              }}
                            />
                            <Button
                              size="sm" variant="outline" className="h-8 text-xs"
                              disabled={newCandidate.positionId !== pos.id || !newCandidate.name.trim()}
                              onClick={() => {
                                if (newCandidate.positionId === pos.id && newCandidate.name.trim()) {
                                  handleAddCandidate();
                                }
                              }}
                            >
                              Add
                            </Button>
                          </div>
                        )}
                      </CardContent>
                    </Card>
                  );
                })}

                {!positions.length && (
                  <div className="text-center py-8 text-muted-foreground text-sm">
                    No positions added yet. Add positions above to get started.
                  </div>
                )}
              </div>
            </ScrollArea>
          </TabsContent>

          {/* VOTERS TAB */}
          <TabsContent value="voters">
            <ScrollArea className="h-[350px] pr-3">
              <div className="space-y-3">
                {election.status !== 'closed' && (
                  <Button onClick={handleAutoPopulateVoters} variant="outline" size="sm" className="gap-2" disabled={addingVoters}>
                    {addingVoters ? <Loader2 className="w-3 h-3 animate-spin" /> : <UserPlus className="w-3 h-3" />}
                    Auto-Populate from Owner Roster
                  </Button>
                )}

                <div className="border rounded-lg overflow-hidden">
                  <table className="w-full text-sm">
                    <thead className="bg-muted">
                      <tr>
                        <th className="px-3 py-2 text-left font-medium">Owner</th>
                        <th className="px-3 py-2 text-left font-medium">Unit</th>
                        <th className="px-3 py-2 text-center font-medium">Consent</th>
                        <th className="px-3 py-2 text-center font-medium">Voted</th>
                      </tr>
                    </thead>
                    <tbody>
                      {voters.map(v => (
                        <tr key={v.id} className="border-t hover:bg-muted/30">
                          <td className="px-3 py-2">
                            <span className="font-medium">{v.owner?.first_name} {v.owner?.last_name}</span>
                            <br />
                            <span className="text-xs text-muted-foreground">{v.owner?.email}</span>
                          </td>
                          <td className="px-3 py-2 text-muted-foreground">{v.unit?.unit_number || v.unit?.address || '—'}</td>
                          <td className="px-3 py-2 text-center">
                            <Button
                              variant="ghost" size="sm"
                              onClick={() => handleToggleConsent(v.id, v.has_consent)}
                              className={v.has_consent ? 'text-primary' : 'text-muted-foreground'}
                            >
                              {v.has_consent ? <CheckCircle2 className="w-4 h-4" /> : <XCircle className="w-4 h-4" />}
                            </Button>
                          </td>
                          <td className="px-3 py-2 text-center">
                            {v.has_voted ? (
                              <Badge variant="default" className="text-xs">Voted</Badge>
                            ) : (
                              <Badge variant="outline" className="text-xs">Pending</Badge>
                            )}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                  {!voters.length && (
                    <div className="text-center py-8 text-muted-foreground text-sm">No eligible voters added.</div>
                  )}
                </div>
              </div>
            </ScrollArea>
          </TabsContent>

          {/* QUORUM TAB */}
          <TabsContent value="quorum">
            <ScrollArea className="h-[350px] pr-3">
              <div className="space-y-4">
                <Card>
                  <CardContent className="p-4 space-y-4">
                    <h4 className="font-semibold text-sm">Quorum Tracking</h4>
                    <div className="grid grid-cols-3 gap-4">
                      <div className="space-y-1">
                        <Label className="text-xs">Online Votes</Label>
                        <div className="text-2xl font-bold">{votedCount}</div>
                      </div>
                      <div className="space-y-1">
                        <Label className="text-xs">Proxies</Label>
                        <Input
                          type="number" min="0"
                          defaultValue={election.proxies_count || 0}
                          onBlur={e => updateElection(election.id, { proxies_count: parseInt(e.target.value) || 0 }).then(onUpdate)}
                          className="h-10 text-lg font-bold"
                        />
                      </div>
                      <div className="space-y-1">
                        <Label className="text-xs">In-Person</Label>
                        <Input
                          type="number" min="0"
                          defaultValue={election.in_person_count || 0}
                          onBlur={e => updateElection(election.id, { in_person_count: parseInt(e.target.value) || 0 }).then(onUpdate)}
                          className="h-10 text-lg font-bold"
                        />
                      </div>
                    </div>
                    <div className="border-t pt-3">
                      <div className="flex justify-between items-center">
                        <span className="font-semibold">Total Participation</span>
                        <span className="text-xl font-bold text-primary">{totalParticipation}</span>
                      </div>
                      {election.quorum_required > 0 && (
                        <div className="mt-2">
                          <Progress value={Math.min((totalParticipation / election.quorum_required) * 100, 100)} className="h-3" />
                          <p className="text-xs text-muted-foreground mt-1">
                            {totalParticipation}/{election.quorum_required} needed
                            {quorumMet ? ' — Quorum Met ✓' : ' — Quorum Not Yet Met'}
                          </p>
                        </div>
                      )}
                    </div>
                  </CardContent>
                </Card>
              </div>
            </ScrollArea>
          </TabsContent>

          {/* RESULTS TAB */}
          <TabsContent value="results">
            <ScrollArea className="h-[350px] pr-3">
              <div className="space-y-4">
                <div className="flex justify-between items-center">
                  <h4 className="font-semibold text-sm">Election Results</h4>
                  <Button variant="outline" size="sm" onClick={handleToggleResultsLock} className="gap-1 text-xs">
                    {election.results_locked ? <Unlock className="w-3 h-3" /> : <Lock className="w-3 h-3" />}
                    {election.results_locked ? 'Unlock Results' : 'Lock Results'}
                  </Button>
                </div>

                {election.results_locked ? (
                  <Card className="border-dashed">
                    <CardContent className="py-8 text-center">
                      <Lock className="w-8 h-8 mx-auto text-muted-foreground mb-2" />
                      <p className="text-muted-foreground text-sm">Results are locked. Unlock to view tallies.</p>
                    </CardContent>
                  </Card>
                ) : (
                  positions.map(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);
                    return (
                      <Card key={pos.id}>
                        <CardHeader className="pb-2 pt-3 px-4">
                          <CardTitle className="text-sm">{pos.title}</CardTitle>
                        </CardHeader>
                        <CardContent className="px-4 pb-3 space-y-2">
                          {posCandidates.map(c => {
                            const count = posResults[c.id] || 0;
                            const pct = totalPosVotes > 0 ? Math.round((count / totalPosVotes) * 100) : 0;
                            return (
                              <div key={c.id} className="space-y-1">
                                <div className="flex justify-between text-sm">
                                  <span className="font-medium">{c.candidate_name}</span>
                                  <span className="text-muted-foreground">{count} votes ({pct}%)</span>
                                </div>
                                <Progress value={pct} className="h-2" />
                              </div>
                            );
                          })}
                          {!posCandidates.length && <p className="text-xs text-muted-foreground">No candidates</p>}
                        </CardContent>
                      </Card>
                    );
                  })
                )}
              </div>
            </ScrollArea>
          </TabsContent>

        </Tabs>
        </div>
      </DialogContent>
    </Dialog>
  );
}
