'use client';

import { useState, useEffect } from 'react';
import { useParams, useRouter } from 'next/navigation';
import Link from 'next/link';
import { Campaign, Proposition, Participant, Vote, PropositionWithVote } from '@/types';
import { campaignService, participantService, propositionService, voteService, settingsService } from '@/lib/services';
import { MarkdownContent } from '@/components/MarkdownContent';
import { PROJECT_CONFIG } from '@/lib/project.config';
import Footer from '@/components/Footer';

// Force dynamic rendering to avoid SSR issues with Supabase
export const dynamic = 'force-dynamic';

export default function PublicVotePage() {
  const params = useParams();
  const router = useRouter();
  const campaignId = params.id as string;
  const participantId = params.participantId as string;
  
  const [campaign, setCampaign] = useState<Campaign | null>(null);
  const [participant, setParticipant] = useState<Participant | null>(null);
  const [propositions, setPropositions] = useState<PropositionWithVote[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState(false);
  
  // Votes temporaires stockés localement
  const [localVotes, setLocalVotes] = useState<Record<string, number>>({});
  const [totalVoted, setTotalVoted] = useState(0);
  const [isRandomOrder, setIsRandomOrder] = useState(false);
  const [isCompactView, setIsCompactView] = useState(false);
  const [currentVisibleProposition, setCurrentVisibleProposition] = useState(1);
  const [isOverBudget, setIsOverBudget] = useState(false);

  useEffect(() => {
    if (campaignId && participantId) {
      loadData();
    }
  }, [campaignId, participantId]);

  // Écouter les changements de connectivité réseau
  useEffect(() => {
    const handleOnline = () => {
      console.log('Connexion réseau rétablie');
      setError('');
    };

    const handleOffline = () => {
      console.log('Connexion réseau perdue');
      setError('Connexion réseau perdue. Veuillez vérifier votre connexion internet.');
    };

    if (typeof window !== 'undefined') {
      window.addEventListener('online', handleOnline);
      window.addEventListener('offline', handleOffline);
    }

    return () => {
      if (typeof window !== 'undefined') {
        window.removeEventListener('online', handleOnline);
        window.removeEventListener('offline', handleOffline);
      }
    };
  }, []);

  // Calculer le total voté à partir des votes locaux
  useEffect(() => {
    const total = Object.values(localVotes).reduce((sum, amount) => sum + amount, 0);
    setTotalVoted(total);
    
    // Vérifier si on dépasse le budget
    if (campaign && total > campaign.budget_per_user) {
      setIsOverBudget(true);
      // Arrêter la vibration après 1 seconde
      setTimeout(() => setIsOverBudget(false), 1000);
    } else {
      setIsOverBudget(false);
    }
  }, [localVotes, campaign]);

  // Observer les propositions visibles
  useEffect(() => {
    if (propositions.length === 0) return;

    const observer = new IntersectionObserver(
      (entries) => {
        let highestVisibleIndex = 1;
        
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            const propositionIndex = parseInt(entry.target.getAttribute('data-proposition-index') || '1');
            if (propositionIndex > highestVisibleIndex) {
              highestVisibleIndex = propositionIndex;
            }
          }
        });
        
        if (highestVisibleIndex > 1) {
          setCurrentVisibleProposition(highestVisibleIndex);
        }
      },
      {
        threshold: 0.3, // La proposition doit être visible à 30% pour être considérée comme active
        rootMargin: '-10% 0px -10% 0px' // Zone de détection réduite
      }
    );

    // Attendre que le DOM soit mis à jour
    setTimeout(() => {
      const propositionElements = document.querySelectorAll('[data-proposition-index]');
      propositionElements.forEach((element) => observer.observe(element));
    }, 100);

    return () => observer.disconnect();
  }, [propositions, isCompactView]);

  const loadData = async () => {
    try {
      setLoading(true);
      setError('');
      
      // Vérifier la connectivité réseau
      if (typeof window !== 'undefined' && !navigator.onLine) {
        throw new Error('Pas de connexion internet. Veuillez vérifier votre connexion réseau.');
      }
      
      const [campaignData, participants, propositionsData] = await Promise.all([
        campaignService.getById(campaignId),
        participantService.getByCampaign(campaignId),
        propositionService.getByCampaign(campaignId)
      ]);
      const participantData = participants.find(p => p.id === participantId);
      
      if (!campaignData) {
        setError('Campagne non trouvée');
        return;
      }
      
      if (!participantData) {
        setError('Participant non trouvé');
        return;
      }
      
      if (campaignData.status !== 'voting') {
        setError('Cette campagne n\'est pas en phase de vote');
        return;
      }
      
      setCampaign(campaignData);
      setParticipant(participantData);
      
      // Charger les votes existants
      const votes = await voteService.getByParticipant(campaignId, participantId);
      
      // Combiner les propositions avec leurs votes
      let propositionsWithVotes = propositionsData.map(proposition => ({
        ...proposition,
        vote: votes.find(vote => vote.proposition_id === proposition.id)
      }));
      
      // Vérifier si l'ordre aléatoire est activé
      const randomizePropositions = await settingsService.getBooleanValue('randomize_propositions', true);
      
      if (randomizePropositions) {
        // Mélanger les propositions de manière aléatoire
        propositionsWithVotes = propositionsWithVotes.sort(() => Math.random() - 0.5);
        setIsRandomOrder(true);
      }
      
      setPropositions(propositionsWithVotes);
      
      // Initialiser les votes locaux avec les votes existants
      const initialVotes: Record<string, number> = {};
      votes.forEach(vote => {
        initialVotes[vote.proposition_id] = vote.amount;
      });
      setLocalVotes(initialVotes);
      
    } catch (error) {
      console.error('Erreur lors du chargement des données:', error);
      let errorMessage = 'Erreur lors du chargement des données';
      
      if (error instanceof Error) {
        errorMessage = error.message;
      } else if (typeof error === 'object' && error !== null) {
        // Essayer d'extraire plus d'informations de l'erreur
        const errorObj = error as any;
        if (errorObj.message) {
          errorMessage = errorObj.message;
        } else if (errorObj.error) {
          errorMessage = errorObj.error;
        } else if (errorObj.details) {
          errorMessage = errorObj.details;
        }
      }
      
      setError(errorMessage);
    } finally {
      setLoading(false);
    }
  };

  const handleVoteChange = (propositionId: string, amount: number) => {
    if (amount === 0) {
      // Si on sélectionne "Aucun vote", on supprime le vote local
      const newLocalVotes = { ...localVotes };
      delete newLocalVotes[propositionId];
      setLocalVotes(newLocalVotes);
    } else {
      // Sinon on met à jour le vote local
      setLocalVotes(prev => ({
        ...prev,
        [propositionId]: amount
      }));
    }
  };

  const handleSubmit = async () => {
    if (totalVoted !== campaign?.budget_per_user) {
      setError(`Vous devez dépenser exactement ${campaign?.budget_per_user}€`);
      return;
    }
    
    setSaving(true);
    setError('');
    
    try {
      // Préparer les votes à sauvegarder (seulement ceux avec amount > 0)
      const votesToSave = Object.entries(localVotes)
        .filter(([_, amount]) => amount > 0)
        .map(([propositionId, amount]) => ({
          proposition_id: propositionId,
          amount
        }));
      
      // Utiliser la méthode atomique pour remplacer tous les votes
      await voteService.replaceVotes(campaignId, participantId, votesToSave);
      
      setSuccess(true);
    } catch (error) {
      console.error('Erreur lors de la validation:', error);
      
      // Améliorer l'affichage de l'erreur
      let errorMessage = 'Erreur lors de la validation des votes';
      
      if (error instanceof Error) {
        errorMessage = error.message;
      } else if (typeof error === 'object' && error !== null) {
        // Essayer d'extraire plus d'informations de l'erreur
        const errorObj = error as any;
        if (errorObj.message) {
          errorMessage = errorObj.message;
        } else if (errorObj.error) {
          errorMessage = errorObj.error;
        } else if (errorObj.details) {
          errorMessage = errorObj.details;
        }
      }
      
      setError(errorMessage);
    } finally {
      setSaving(false);
    }
  };

  const getSpendingTiers = () => {
    if (!campaign) return [];
    return campaign.spending_tiers.split(',').map(tier => parseInt(tier.trim())).filter(tier => tier > 0);
  };

  const getVoteStatus = () => {
    if (!campaign) return { status: 'error', message: 'Campagne non trouvée' };
    
    const remaining = campaign.budget_per_user - totalVoted;
    
    if (remaining === 0) {
      return { status: 'success', message: 'Budget complet ! Vous pouvez valider votre vote.' };
    } else if (remaining > 0) {
      return { status: 'warning', message: `Il vous reste ${remaining}€ à dépenser` };
    } else {
      return { status: 'error', message: `Vous avez dépensé ${Math.abs(remaining)}€ de trop` };
    }
  };

  if (loading) {
    return (
      <div className="min-h-screen bg-gray-50 flex items-center justify-center">
        <div className="text-center">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600 mx-auto"></div>
          <p className="mt-4 text-gray-600">Chargement de la page de vote...</p>
        </div>
      </div>
    );
  }

  if (error && !campaign) {
    return (
      <div className="min-h-screen bg-gray-50 flex items-center justify-center">
        <div className="text-center">
          <div className="bg-white rounded-lg shadow-lg p-8 max-w-md mx-auto">
            <svg className="mx-auto h-12 w-12 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
            </svg>
            <h2 className="mt-4 text-lg font-medium text-gray-900">Erreur</h2>
            <p className="mt-2 text-sm text-gray-600">{error}</p>
            <Link
              href="/"
              className="mt-4 inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700"
            >
              Retour à l'accueil
            </Link>
          </div>
        </div>
      </div>
    );
  }

  if (success) {
    return (
      <div className="min-h-screen bg-gray-50 flex items-center justify-center">
        <div className="text-center">
          <div className="bg-white rounded-lg shadow-lg p-8 max-w-md mx-auto">
            <svg className="mx-auto h-12 w-12 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
            <h2 className="mt-4 text-lg font-medium text-gray-900">Vote enregistré !</h2>
            <p className="mt-2 text-sm text-gray-600">
              Votre vote a été enregistré avec succès. Vous pouvez revenir modifier vos choix tant que la campagne est en cours.
            </p>
            <button
              onClick={() => window.location.reload()}
              className="mt-4 inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700"
            >
              Retour à mon vote
            </button>
          </div>
        </div>
      </div>
    );
  }

  const voteStatus = getVoteStatus();
  const spendingTiers = getSpendingTiers();

  return (
    <div className="min-h-screen bg-gray-50 vote-page">
      {/* Header fixe avec le total et le bouton de validation */}
      <div className="sticky top-0 z-40 bg-white shadow-sm border-b border-gray-200">
        <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center space-x-4">
              <div>
                <h1 className="text-lg font-semibold text-gray-900">{campaign?.title}</h1>
                <p className="text-lg font-bold text-indigo-600">
                  {participant?.first_name} {participant?.last_name}
                </p>
              </div>
            </div>
            
            <div className="flex items-center space-x-4">
              <div className="text-right">
                <div className={`text-2xl font-bold transition-all duration-300 ${
                  isOverBudget 
                    ? 'text-red-600 animate-pulse' 
                    : totalVoted === campaign?.budget_per_user 
                      ? 'text-green-600 scale-105' 
                      : totalVoted > 0 
                        ? 'text-indigo-600' 
                        : 'text-gray-900'
                } ${isOverBudget ? 'animate-bounce' : ''}`}>
                  {totalVoted}€ / {campaign?.budget_per_user}€
                </div>
                <div className={`text-sm font-medium transition-colors duration-300 ${
                  voteStatus.status === 'success' ? 'text-green-600' :
                  voteStatus.status === 'warning' ? 'text-yellow-600' :
                  'text-red-600'
                }`}>
                  {voteStatus.message}
                </div>
              </div>
              
              <button
                onClick={handleSubmit}
                disabled={saving || totalVoted !== campaign?.budget_per_user}
                className={`px-6 py-3 text-sm font-medium rounded-lg transition-all duration-200 ${
                  totalVoted === campaign?.budget_per_user
                    ? 'bg-green-600 text-white hover:bg-green-700 shadow-lg'
                    : 'bg-gray-300 text-gray-500 cursor-not-allowed'
                }`}
              >
                {saving ? 'Enregistrement...' : 'Valider mon vote'}
              </button>
            </div>
          </div>
        </div>
      </div>

      <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8 pb-20">
        {/* Informations de la campagne */}
        <div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-8">
          <div className="grid grid-cols-1 md:grid-cols-1 gap-6">
            <div>
              <MarkdownContent 
                content={campaign?.description || ''} 
                className="mt-1 text-base font-medium text-gray-900"
              />
            </div>
          </div>
        </div>

        {/* Message discret sur l'ordre aléatoire */}
        {isRandomOrder && (
          <div className="mb-6 text-center">
            <span className="inline-flex items-center px-2 py-1 rounded-full text-xs text-gray-400 bg-gray-50 border border-gray-100">
              <svg className="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
                <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
              </svg>
              Les propositions sont affichées dans un ordre aléatoire pour éviter les biais liés à l'ordre de présentation
            </span>
          </div>
        )}

        {/* Propositions */}
        {propositions.length === 0 ? (
          <div className="text-center py-12">
            <svg className="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
            </svg>
            <h3 className="mt-2 text-sm font-medium text-gray-900">Aucune proposition</h3>
            <p className="mt-1 text-sm text-gray-500">Aucune proposition n'a été soumise pour cette campagne.</p>
          </div>
        ) : (
          <div className={`${isCompactView ? 'space-y-3' : 'space-y-6'}`}>
            {propositions.map((proposition, index) => (
              <div 
                key={proposition.id} 
                data-proposition-index={index + 1}
                className={`rounded-lg shadow-sm border overflow-hidden transition-all duration-200 relative ${
                  localVotes[proposition.id] && localVotes[proposition.id] > 0
                    ? 'border-indigo-400 shadow-lg bg-indigo-100'
                    : 'bg-white border-gray-200'
                }`}
              >
                {!isCompactView && (
                  <div className="absolute -top-1 left-4 bg-white px-2 text-xs text-gray-500 font-medium z-10 border border-gray-200 rounded-t">
                    Proposition
                  </div>
                )}
                                  <div className={`${isCompactView ? 'p-4' : 'p-6'}`}>
                    <div className="flex items-start justify-between">
                      <div className="flex-1">
                        <h3 className={`font-medium text-gray-900 ${isCompactView ? 'text-base mb-1' : 'text-lg mb-2'}`}>
                          {proposition.title}
                        </h3>
                        {!isCompactView && (
                          <MarkdownContent 
                            content={proposition.description} 
                            className="text-sm text-gray-600 mb-4"
                          />
                        )}
                      </div>
                    </div>
                    
                    <div className={isCompactView ? 'mt-3' : 'mt-6'}>
                    {!isCompactView && (
                      <label className="block text-sm font-medium text-gray-700 mb-3">
                        Pour cette proposition, vous investissez :
                      </label>
                    )}
                    <div className="space-y-4">
                      {/* Slider */}
                      <div className="relative">
                        <input
                          type="range"
                          min="0"
                          max={spendingTiers.length}
                          step="1"
                          value={localVotes[proposition.id] ? (localVotes[proposition.id] === 0 ? 0 : spendingTiers.indexOf(localVotes[proposition.id]) + 1) : 0}
                          onChange={(e) => {
                            const index = parseInt(e.target.value);
                            const amount = index === 0 ? 0 : spendingTiers[index - 1];
                            handleVoteChange(proposition.id, amount);
                          }}
                          className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider"
                        />
                        
                        {/* Marqueurs des paliers */}
                        <div className="relative mt-3 mb-16" style={{ marginLeft: '12px', marginRight: '24px' }}>
                          {/* Marqueur 0€ */}
                          <div className="absolute text-center" style={{ left: '0%', transform: 'translateX(-12px)' }}>
                            <div className="w-3 h-3 bg-gray-400 rounded-full mx-auto mb-2"></div>
                            <span className="text-xs text-gray-600 font-medium whitespace-nowrap">0€</span>
                          </div>
                          
                          {/* Marqueurs des paliers */}
                          {spendingTiers.map((tier, index) => {
                            // Calcul correct de la position pour correspondre au slider
                            const position = ((index + 1) / spendingTiers.length) * 100;
                            return (
                              <div 
                                key={`tier-${index}-${tier}`} 
                                className="absolute text-center" 
                                style={{ 
                                  left: `${position}%`,
                                  transform: 'translateX(-12px)'
                                }}
                              >
                                <div className="w-3 h-3 bg-indigo-500 rounded-full mx-auto mb-2"></div>
                                <span className="text-xs text-gray-600 font-medium whitespace-nowrap">{tier}€</span>
                              </div>
                            );
                          })}
                        </div>
                      </div>
                      
                      {/* Valeur sélectionnée */}
                      {(localVotes[proposition.id] && localVotes[proposition.id] > 0) && !isCompactView && (
                        <div className="text-center mt-12">
                          <span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-indigo-100 text-indigo-800">
                            Vote sélectionné : {localVotes[proposition.id]}€
                          </span>
                        </div>
                      )}
                    </div>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}

        {error && (
          <div className="mt-6 bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-md">
            {error}
          </div>
        )}

        {/* Footer discret */}
        <Footer />
      </div>

      {/* Barre fixe en bas */}
      <div className="fixed bottom-0 left-0 right-0 z-40 bg-white shadow-lg border-t border-gray-200">
        <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-3">
          <div className="flex items-center justify-between">
            <div className="text-sm text-gray-600">
              Proposition {currentVisibleProposition} / {propositions.length}
            </div>
            
            <div className="flex items-center space-x-2 text-xs text-gray-500">
              <span>Juste les titres</span>
              <button
                onClick={() => setIsCompactView(!isCompactView)}
                className={`relative inline-flex h-5 w-9 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 ${
                  !isCompactView ? 'bg-indigo-600' : 'bg-gray-200'
                }`}
              >
                <span
                  className={`inline-block h-3 w-3 transform rounded-full bg-white transition-transform ${
                    !isCompactView ? 'translate-x-5' : 'translate-x-1'
                  }`}
                />
              </button>
              <span>Avec descriptions</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
