import React, { useState, useEffect, useCallback } from 'react';
import { useParams, useSearchParams } from 'react-router-dom';
import { supabase } from '@/integrations/supabase/client';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { ScrollArea } from '@/components/ui/scroll-area';
import { useToast } from '@/hooks/use-toast';
import { Vote, CheckCircle2, Clock, Lock, Loader2, AlertTriangle, RefreshCw, Shield, KeyRound } from 'lucide-react';
import { format } from 'date-fns';

/**
 * Public voting page — accessed via /vote/:electionId?token=xxx or with access code entry.
 * No login required.
 */
export default function ElectionVotePage() {
  const { electionId } = useParams();
  const [searchParams] = useSearchParams();
  const urlToken = searchParams.get('token');
  const { toast } = useToast();

  const [voteToken, setVoteToken] = useState(urlToken || '');
  const [accessCode, setAccessCode] = useState('');
  const [authenticated, setAuthenticated] = useState(!!urlToken);
  const [election, setElection] = useState(null);
  const [positions, setPositions] = useState([]);
  const [candidates, setCandidates] = useState([]);
  const [voterRecord, setVoterRecord] = useState(null);
  const [selections, setSelections] = useState({}); // { positionId: [candidateId, ...] }
  const [submitted, setSubmitted] = useState(false);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState(null);
  const [authError, setAuthError] = useState('');

  // Load election info (public, no auth needed)
  useEffect(() => {
    if (!electionId) return;
    (async () => {
      const { data: el } = await supabase
        .from('elections')
        .select('*, association:association_id(id, name, logo_url)')
        .eq('id', electionId)
        .single();
      setElection(el || null);
      if (!urlToken) setLoading(false);
    })();
  }, [electionId, urlToken]);

  const authenticateVoter = useCallback(async (token) => {
    setLoading(true);
    setAuthError('');
    try {
      const { data: voters, error: vErr } = await supabase
        .rpc('lookup_voter_by_token', { p_vote_token: token });
      const voter = voters?.[0] || null;
      if (vErr || !voter) {
        setAuthError('Invalid token or access code.');
        setLoading(false);
        return;
      }
      setVoterRecord(voter);
      setVoteToken(token);
      setAuthenticated(true);

      // Fetch positions & candidates
      const { data: pos } = await supabase
        .from('election_positions').select('*')
        .eq('election_id', electionId).order('sort_order');
      setPositions(pos || []);

      if (pos?.length) {
        const { data: cands } = await supabase
          .from('election_candidates').select('*')
          .in('position_id', pos.map(p => p.id)).order('sort_order');
        setCandidates(cands || []);
      }

      // Load existing ballot
      if (voter.has_voted) {
        const { data: ballot } = await supabase
          .from('election_ballots').select('*')
          .eq('election_id', electionId).eq('vote_token', token);
        const sels = {};
        (ballot || []).forEach(b => {
          if (!sels[b.position_id]) sels[b.position_id] = [];
          sels[b.position_id].push(b.candidate_id);
        });
        setSelections(sels);
      }
    } catch (err) {
      console.error(err);
      setError('Something went wrong.');
    } finally {
      setLoading(false);
    }
  }, [electionId]);

  // Auto-authenticate if URL has token
  useEffect(() => {
    if (urlToken && electionId) authenticateVoter(urlToken);
  }, [urlToken, electionId, authenticateVoter]);

  const handleAccessCodeSubmit = async (e) => {
    e.preventDefault();
    const code = accessCode.trim().toUpperCase();
    if (!code) return;
    setLoading(true);
    try {
      // Look up voter by access code
      const { data: voters } = await supabase
        .rpc('lookup_voter_by_access_code', { p_election_id: electionId, p_access_code: code });
      const voter = voters?.[0] || null;
      if (!voter?.vote_token) {
        setAuthError('Invalid access code. Please check your printed notice.');
        setLoading(false);
        return;
      }
      await authenticateVoter(voter.vote_token);
    } catch {
      setAuthError('Invalid access code.');
      setLoading(false);
    }
  };

  const handleToggleCandidate = (positionId, candidateId, seatsAvailable) => {
    setSelections(prev => {
      const current = prev[positionId] || [];
      if (current.includes(candidateId)) {
        return { ...prev, [positionId]: current.filter(id => id !== candidateId) };
      }
      if (current.length >= seatsAvailable) {
        // Replace oldest selection if at limit
        return { ...prev, [positionId]: [...current.slice(1), candidateId] };
      }
      return { ...prev, [positionId]: [...current, candidateId] };
    });
  };

  const handleSubmitBallot = async () => {
    if (!voteToken) return;
    setSubmitting(true);
    try {
      await supabase.from('election_ballots').delete()
        .eq('election_id', electionId).eq('vote_token', voteToken);

      const ballots = [];
      Object.entries(selections).forEach(([posId, candIds]) => {
        (candIds || []).forEach(candId => {
          ballots.push({
            election_id: electionId,
            position_id: posId,
            candidate_id: candId,
            vote_token: voteToken
          });
        });
      });
      const { error: insertErr } = await supabase.from('election_ballots').insert(ballots);
      if (insertErr) throw insertErr;

      await supabase.rpc('mark_voter_as_voted', { p_vote_token: voteToken });

      await supabase.from('election_audit_log').insert({
        election_id: electionId,
        voter_description: `Token voter (${voteToken.substring(0, 8)}...)`,
        action: voterRecord?.has_voted ? 'vote_changed' : 'voted'
      });

      setSubmitted(true);
      toast({ title: 'Vote Submitted!', description: 'Your ballot has been recorded securely.' });
    } catch (err) {
      console.error(err);
      toast({ variant: 'destructive', title: 'Error', description: 'Failed to submit ballot.' });
    } finally {
      setSubmitting(false);
    }
  };

  const isVotingOpen = election?.status === 'active' &&
    (!election?.voting_end || new Date(election.voting_end) > new Date());
  const allPositionsSelected = positions.every(p => (selections[p.id] || []).length > 0);

  // Loading
  if (loading && !election) {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center">
        <div className="h-10 w-10 animate-spin rounded-full border-4 border-primary border-t-transparent" />
      </div>
    );
  }

  // Error
  if (error) {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center p-4">
        <Card className="max-w-md w-full border-destructive/30">
          <CardContent className="py-12 text-center">
            <AlertTriangle className="w-12 h-12 mx-auto text-destructive mb-4" />
            <h2 className="text-xl font-bold mb-2">Voting Error</h2>
            <p className="text-muted-foreground">{error}</p>
          </CardContent>
        </Card>
      </div>
    );
  }

  // Access code entry screen (no token in URL)
  if (!authenticated) {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center p-4">
        <Card className="max-w-md w-full">
          <CardContent className="py-8 space-y-6">
            <div className="text-center space-y-3">
              {election?.association?.logo_url && (
                <img src={election.association.logo_url} alt="" className="h-12 mx-auto object-contain" />
              )}
              <h1 className="text-2xl font-bold">{election?.title || 'Election'}</h1>
              <p className="text-muted-foreground text-sm">{election?.association?.name}</p>
            </div>

            <div className="border-t pt-6">
              <div className="flex items-center gap-2 mb-4">
                <KeyRound className="w-5 h-5 text-primary" />
                <h2 className="font-semibold">Enter Your Access Code</h2>
              </div>
              <p className="text-sm text-muted-foreground mb-4">
                Enter the 6-character access code from your printed election notice to cast your ballot.
              </p>
              <form onSubmit={handleAccessCodeSubmit} className="space-y-3">
                <Input
                  value={accessCode}
                  onChange={e => { setAccessCode(e.target.value.toUpperCase()); setAuthError(''); }}
                  placeholder="e.g. A3F9K2"
                  maxLength={6}
                  className="text-center text-2xl tracking-[0.3em] font-mono uppercase h-14"
                  autoFocus
                />
                {authError && <p className="text-sm text-destructive text-center">{authError}</p>}
                <Button type="submit" className="w-full gap-2" disabled={loading || accessCode.length < 6}>
                  {loading ? <Loader2 className="w-4 h-4 animate-spin" /> : <Vote className="w-4 h-4" />}
                  Access Ballot
                </Button>
              </form>
            </div>

            <p className="text-xs text-muted-foreground text-center flex items-center justify-center gap-1">
              <Shield className="w-3 h-3" /> Secret ballot — your vote is anonymous
            </p>
          </CardContent>
        </Card>
      </div>
    );
  }

  // Loading after auth
  if (loading) {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center">
        <div className="h-10 w-10 animate-spin rounded-full border-4 border-primary border-t-transparent" />
      </div>
    );
  }

  // Consent required
  if (!voterRecord?.has_consent) {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center p-4">
        <Card className="max-w-md w-full">
          <CardContent className="py-12 text-center">
            <AlertTriangle className="w-12 h-12 mx-auto text-amber-500 mb-4" />
            <h2 className="text-xl font-bold mb-2">Electronic Consent Required</h2>
            <p className="text-muted-foreground">You must provide electronic voting consent before casting your ballot. Please contact your association manager.</p>
          </CardContent>
        </Card>
      </div>
    );
  }

  // Submitted
  if (submitted) {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center p-4">
        <Card className="max-w-md w-full border-primary/30">
          <CardContent className="py-12 text-center space-y-4">
            <CheckCircle2 className="w-20 h-20 mx-auto text-primary" />
            <h2 className="text-2xl font-bold">Vote Submitted!</h2>
            <p className="text-muted-foreground">Your ballot has been securely recorded.</p>
            <div className="bg-muted rounded-lg p-4 space-y-2">
              <p className="text-xs text-muted-foreground font-medium">CONFIRMATION RECEIPT</p>
              <p className="text-sm"><strong>Election:</strong> {election.title}</p>
              <p className="text-sm"><strong>Timestamp:</strong> {format(new Date(), 'MMM d, yyyy h:mm:ss a')}</p>
            </div>
            <div className="flex items-center justify-center gap-2 text-xs text-muted-foreground">
              <Shield className="w-3 h-3" />
              <span>Secret ballot — your selections are anonymous</span>
            </div>
            {isVotingOpen && (
              <Button variant="outline" className="gap-2" onClick={() => { setSubmitted(false); authenticateVoter(voteToken); }}>
                <RefreshCw className="w-4 h-4" /> Change My Vote
              </Button>
            )}
          </CardContent>
        </Card>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-background">
      <div className="max-w-2xl mx-auto p-4 sm:p-8 space-y-6">
        {/* Header */}
        <div className="text-center space-y-3">
          {election.association?.logo_url && (
            <img src={election.association.logo_url} alt="" className="h-12 mx-auto object-contain" />
          )}
          <h1 className="text-2xl sm:text-3xl font-bold">{election.title}</h1>
          <p className="text-muted-foreground">{election.association?.name}</p>
          {election.description && <p className="text-sm text-muted-foreground">{election.description}</p>}
          <div className="flex justify-center gap-3">
            <Badge variant={isVotingOpen ? 'default' : 'secondary'}>
              {isVotingOpen ? 'Voting Open' : 'Voting Closed'}
            </Badge>
            {election.voting_end && (
              <span className="text-xs text-muted-foreground flex items-center gap-1">
                <Clock className="w-3 h-3" />
                {isVotingOpen ? 'Closes' : 'Closed'}: {format(new Date(election.voting_end), 'MMM d, yyyy h:mm a')}
              </span>
            )}
          </div>
        </div>

        {!isVotingOpen ? (
          <Card className="border-dashed">
            <CardContent className="py-12 text-center">
              <Lock className="w-10 h-10 mx-auto text-muted-foreground mb-3" />
              <p className="text-muted-foreground font-medium">Voting is currently closed.</p>
            </CardContent>
          </Card>
        ) : (
          <>
            {voterRecord?.has_voted && (
              <div className="bg-primary/5 border border-primary/20 rounded-lg p-3 text-center text-sm">
                <RefreshCw className="w-4 h-4 inline mr-1" />
                You have already voted. You may update your selections below until the deadline.
              </div>
            )}

            <ScrollArea className="max-h-[500px]">
              <div className="space-y-4">
                {positions.map(pos => {
                  const posCandidates = candidates.filter(c => c.position_id === pos.id);
                  const selected = selections[pos.id] || [];
                  const seats = pos.seats_available || 1;
                  return (
                    <Card key={pos.id}>
                      <CardHeader className="pb-2 pt-4 px-5">
                        <CardTitle className="text-base">{pos.title}</CardTitle>
                        <p className="text-xs text-muted-foreground">
                          Select up to {seats} candidate{seats > 1 ? 's' : ''} — {selected.length}/{seats} selected
                        </p>
                      </CardHeader>
                      <CardContent className="px-5 pb-4 space-y-3">
                        {posCandidates.map(c => {
                          const isChecked = selected.includes(c.id);
                          return (
                            <div
                              key={c.id}
                              className={`flex items-start space-x-3 border rounded-lg p-3 cursor-pointer transition-colors ${isChecked ? 'bg-primary/5 border-primary/30' : 'hover:bg-muted/50'}`}
                              onClick={() => handleToggleCandidate(pos.id, c.id, seats)}
                            >
                              <Checkbox
                                checked={isChecked}
                                onCheckedChange={() => handleToggleCandidate(pos.id, c.id, seats)}
                                className="mt-0.5"
                                id={`tc-${c.id}`}
                              />
                              <Label htmlFor={`tc-${c.id}`} className="flex-1 cursor-pointer">
                                <span className="font-medium">{c.candidate_name}</span>
                                {c.bio && <p className="text-xs text-muted-foreground mt-0.5">{c.bio}</p>}
                              </Label>
                            </div>
                          );
                        })}
                      </CardContent>
                    </Card>
                  );
                })}
              </div>
            </ScrollArea>

            <div className="flex flex-col items-center gap-3 pt-4">
              <Button
                onClick={handleSubmitBallot}
                disabled={submitting || !allPositionsSelected}
                size="lg"
                className="gap-2 w-full sm:w-auto"
              >
                {submitting ? <Loader2 className="w-4 h-4 animate-spin" /> : <Vote className="w-4 h-4" />}
                {voterRecord?.has_voted ? 'Update My Vote' : 'Submit Ballot'}
              </Button>
              {!allPositionsSelected && (
                <p className="text-xs text-muted-foreground">Please select at least one candidate for every position.</p>
              )}
              <p className="text-xs text-muted-foreground flex items-center gap-1">
                <Shield className="w-3 h-3" /> Your vote is anonymous — secret ballot per FL §718/§720
              </p>
            </div>
          </>
        )}
      </div>
    </div>
  );
}
