import { useState, useCallback } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { useAuth } from '@/contexts/AuthContext';

export function useElections() {
  const [loading, setLoading] = useState(false);
  const { toast } = useToast();
  const { user } = useAuth();

  const fetchElections = useCallback(async (associationId = null, status = null) => {
    setLoading(true);
    try {
      let query = supabase
        .from('elections')
        .select(`*, association:association_id(id, name)`)
        .order('created_at', { ascending: false });

      if (associationId) query = query.eq('association_id', associationId);
      if (status && status !== 'all') query = query.eq('status', status);

      const { data, error } = await query;
      if (error) throw error;
      return data || [];
    } catch (err) {
      console.error('Error fetching elections:', err);
      return [];
    } finally {
      setLoading(false);
    }
  }, []);

  const fetchElection = useCallback(async (electionId) => {
    try {
      const { data, error } = await supabase
        .from('elections')
        .select(`*, association:association_id(id, name)`)
        .eq('id', electionId)
        .single();
      if (error) throw error;
      return data;
    } catch (err) {
      console.error('Error fetching election:', err);
      return null;
    }
  }, []);

  const createElection = async (electionData) => {
    setLoading(true);
    try {
      const { data, error } = await supabase
        .from('elections')
        .insert({ ...electionData, created_by: user.id })
        .select()
        .single();
      if (error) throw error;
      toast({ title: "Success", description: "Election created successfully." });
      return data;
    } catch (err) {
      console.error('Error creating election:', err);
      toast({ variant: "destructive", title: "Error", description: "Failed to create election." });
      return null;
    } finally {
      setLoading(false);
    }
  };

  const updateElection = useCallback(async (id, updates) => {
    setLoading(true);
    try {
      const { error } = await supabase.from('elections').update(updates).eq('id', id);
      if (error) throw error;
      toast({ title: "Updated", description: "Election updated." });
      return true;
    } catch (err) {
      console.error('Error updating election:', err);
      toast({ variant: "destructive", title: "Error", description: err.message });
      return false;
    } finally {
      setLoading(false);
    }
  }, [toast]);

  const deleteElection = async (id) => {
    setLoading(true);
    try {
      const { error } = await supabase.from('elections').delete().eq('id', id);
      if (error) throw error;
      toast({ title: "Deleted", description: "Election deleted." });
      return true;
    } catch (err) {
      toast({ variant: "destructive", title: "Error", description: err.message });
      return false;
    } finally {
      setLoading(false);
    }
  };

  // Positions
  const fetchPositions = useCallback(async (electionId) => {
    const { data, error } = await supabase
      .from('election_positions')
      .select('*')
      .eq('election_id', electionId)
      .order('sort_order');
    if (error) { console.error(error); return []; }
    return data || [];
  }, []);

  const createPosition = async (positionData) => {
    try {
      const { data, error } = await supabase.from('election_positions').insert(positionData).select().single();
      if (error) throw error;
      return data;
    } catch (err) {
      toast({ variant: "destructive", title: "Error", description: err.message });
      return null;
    }
  };

  const deletePosition = async (id) => {
    const { error } = await supabase.from('election_positions').delete().eq('id', id);
    if (error) toast({ variant: "destructive", title: "Error", description: error.message });
    return !error;
  };

  // Candidates
  const fetchCandidates = useCallback(async (positionId) => {
    const { data, error } = await supabase
      .from('election_candidates')
      .select('*')
      .eq('position_id', positionId)
      .order('sort_order');
    if (error) { console.error(error); return []; }
    return data || [];
  }, []);

  const fetchAllCandidates = useCallback(async (electionId) => {
    const positions = await fetchPositions(electionId);
    const posIds = positions.map(p => p.id);
    if (!posIds.length) return [];
    const { data, error } = await supabase
      .from('election_candidates')
      .select('*')
      .in('position_id', posIds)
      .order('sort_order');
    if (error) { console.error(error); return []; }
    return data || [];
  }, [fetchPositions]);

  const createCandidate = async (candidateData) => {
    try {
      const { data, error } = await supabase.from('election_candidates').insert(candidateData).select().single();
      if (error) throw error;
      return data;
    } catch (err) {
      toast({ variant: "destructive", title: "Error", description: err.message });
      return null;
    }
  };

  const deleteCandidate = async (id) => {
    const { error } = await supabase.from('election_candidates').delete().eq('id', id);
    if (error) toast({ variant: "destructive", title: "Error", description: error.message });
    return !error;
  };

  // Eligible voters
  const fetchEligibleVoters = useCallback(async (electionId) => {
    const { data, error } = await supabase
      .from('election_eligible_voters')
      .select(`*, owner:owner_id(id, first_name, last_name, email, account_number), unit:unit_id(id, unit_number, address)`)
      .eq('election_id', electionId);
    if (error) { console.error(error); return []; }
    return data || [];
  }, []);

  const addEligibleVoters = async (voters) => {
    try {
      const { error } = await supabase.from('election_eligible_voters').insert(voters);
      if (error) throw error;
      toast({ title: "Voters Added", description: `${voters.length} eligible voter(s) added.` });
      return true;
    } catch (err) {
      toast({ variant: "destructive", title: "Error", description: err.message });
      return false;
    }
  };

  const updateVoterConsent = async (voterId, hasConsent) => {
    const updates = { has_consent: hasConsent };
    if (hasConsent) updates.consent_date = new Date().toISOString();
    const { error } = await supabase.from('election_eligible_voters').update(updates).eq('id', voterId);
    if (error) toast({ variant: "destructive", title: "Error", description: error.message });
    return !error;
  };

  // Voting
  const castBallot = async (electionId, voteToken, selections) => {
    setLoading(true);
    try {
      // Delete existing ballots for this token in this election
      await supabase.from('election_ballots').delete().eq('election_id', electionId).eq('vote_token', voteToken);

      // Insert new ballots
      const ballots = selections.map(s => ({
        election_id: electionId,
        position_id: s.position_id,
        candidate_id: s.candidate_id,
        vote_token: voteToken
      }));
      const { error } = await supabase.from('election_ballots').insert(ballots);
      if (error) throw error;

      // Mark voter as having voted
      await supabase.rpc('mark_voter_as_voted', { p_vote_token: voteToken });

      // Add audit log entry (no vote details)
      await supabase.from('election_audit_log').insert({
        election_id: electionId,
        voter_description: `Unit voter (token: ${voteToken.substring(0, 8)}...)`,
        action: 'voted'
      });

      toast({ title: "Vote Submitted", description: "Your ballot has been recorded securely." });
      return true;
    } catch (err) {
      console.error('Error casting ballot:', err);
      toast({ variant: "destructive", title: "Error", description: err.message });
      return false;
    } finally {
      setLoading(false);
    }
  };

  // Results (anonymous tallying)
  const fetchResults = useCallback(async (electionId) => {
    const { data, error } = await supabase
      .from('election_ballots')
      .select('position_id, candidate_id')
      .eq('election_id', electionId);
    if (error) { console.error(error); return []; }
    return data || [];
  }, []);

  const fetchAuditLog = useCallback(async (electionId) => {
    const { data, error } = await supabase
      .from('election_audit_log')
      .select('*')
      .eq('election_id', electionId)
      .order('created_at', { ascending: false });
    if (error) { console.error(error); return []; }
    return data || [];
  }, []);

  // Get voter record for current user
  const getMyVoterRecord = useCallback(async (electionId) => {
    const { data: owners } = await supabase
      .from('owners')
      .select('id')
      .eq('user_id', user?.id)
      .neq('status', 'archived');
    
    if (!owners?.length) return null;
    
    const ownerIds = owners.map(o => o.id);
    const { data, error } = await supabase
      .from('election_eligible_voters')
      .select('*')
      .eq('election_id', electionId)
      .in('owner_id', ownerIds)
      .limit(1)
      .single();
    
    if (error) return null;
    return data;
  }, [user?.id]);

  // Get existing ballot for a token
  const getMyBallot = useCallback(async (electionId, voteToken) => {
    const { data, error } = await supabase
      .from('election_ballots')
      .select('*')
      .eq('election_id', electionId)
      .eq('vote_token', voteToken);
    if (error) { console.error(error); return []; }
    return data || [];
  }, []);

  return {
    loading,
    fetchElections,
    fetchElection,
    createElection,
    updateElection,
    deleteElection,
    fetchPositions,
    createPosition,
    deletePosition,
    fetchCandidates,
    fetchAllCandidates,
    createCandidate,
    deleteCandidate,
    fetchEligibleVoters,
    addEligibleVoters,
    updateVoterConsent,
    castBallot,
    fetchResults,
    fetchAuditLog,
    getMyVoterRecord,
    getMyBallot
  };
}
