import { useEffect, useState } from 'react';
import {
  getTrackHistory,
  TrackHistory as TrackHistoryItem,
  TrackHistoryError,
  TrackHistoryAction,
} from '../services/trackHistoryService';
import { LoadingSpinner } from '@/components/ui/loading-spinner';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import {
  History,
  Calendar,
  Plus,
  Edit,
  Trash2,
  Eye,
  EyeOff,
  RotateCcw,
  ChevronLeft,
  ChevronRight,
} from 'lucide-react';

/**
 * TrackHistory Component
 * T0330: Composant pour afficher l'historique des modifications d'un track avec timeline
 */

interface TrackHistoryProps {
  trackId: string;
  className?: string;
  limit?: number;
}

export function TrackHistory({
  trackId,
  className,
  limit = 50,
}: TrackHistoryProps) {
  const [history, setHistory] = useState<TrackHistoryItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [total, setTotal] = useState(0);
  const [currentOffset, setCurrentOffset] = useState(0);
  const [currentLimit] = useState(limit);

  useEffect(() => {
    loadHistory();
  }, [trackId, currentOffset]);

  const loadHistory = async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await getTrackHistory(trackId, {
        limit: currentLimit,
        offset: currentOffset,
      });
      setHistory(data.history);
      setTotal(data.total);
    } catch (err) {
      if (err instanceof TrackHistoryError) {
        setError(err.message);
      } else {
        setError("Impossible de charger l'historique");
      }
    } finally {
      setLoading(false);
    }
  };

  const formatDate = (dateString: string): string => {
    const date = new Date(dateString);
    return new Intl.DateTimeFormat('fr-FR', {
      year: 'numeric',
      month: 'long',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    }).format(date);
  };

  const getActionIcon = (action: TrackHistoryAction) => {
    switch (action) {
      case 'created':
        return Plus;
      case 'updated':
        return Edit;
      case 'deleted':
        return Trash2;
      case 'published':
        return Eye;
      case 'unpublished':
        return EyeOff;
      case 'restored':
        return RotateCcw;
      default:
        return History;
    }
  };

  const getActionLabel = (action: TrackHistoryAction): string => {
    switch (action) {
      case 'created':
        return 'Créé';
      case 'updated':
        return 'Modifié';
      case 'deleted':
        return 'Supprimé';
      case 'published':
        return 'Publié';
      case 'unpublished':
        return 'Dépublié';
      case 'restored':
        return 'Restauré';
      default:
        return action;
    }
  };

  const getActionColor = (action: TrackHistoryAction): string => {
    switch (action) {
      case 'created':
        return 'text-green-600 bg-green-50';
      case 'updated':
        return 'text-blue-600 bg-blue-50';
      case 'deleted':
        return 'text-red-600 bg-red-50';
      case 'published':
        return 'text-purple-600 bg-purple-50';
      case 'unpublished':
        return 'text-orange-600 bg-orange-50';
      case 'restored':
        return 'text-cyan-600 bg-cyan-50';
      default:
        return 'text-gray-600 bg-gray-50';
    }
  };

  const parseValue = (value?: string): any => {
    if (!value) return null;
    try {
      return JSON.parse(value);
    } catch {
      return value;
    }
  };

  const formatValue = (value: any): string => {
    if (value === null || value === undefined) return '';
    if (typeof value === 'string') return value;
    if (typeof value === 'object') {
      return JSON.stringify(value, null, 2);
    }
    return String(value);
  };

  const handlePreviousPage = () => {
    if (currentOffset > 0) {
      setCurrentOffset(Math.max(0, currentOffset - currentLimit));
    }
  };

  const handleNextPage = () => {
    if (currentOffset + currentLimit < total) {
      setCurrentOffset(currentOffset + currentLimit);
    }
  };

  if (loading) {
    return (
      <div className={cn('flex items-center justify-center p-4', className)}>
        <LoadingSpinner size="sm" />
      </div>
    );
  }

  if (error) {
    return (
      <div className={cn('p-4', className)}>
        <Alert variant="destructive">
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      </div>
    );
  }

  const hasPreviousPage = currentOffset > 0;
  const hasNextPage = currentOffset + currentLimit < total;

  return (
    <div className={cn('space-y-4', className)}>
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <History className="h-5 w-5" />
          <h3 className="text-lg font-semibold">
            Historique des modifications
          </h3>
          {total > 0 && (
            <span className="text-sm text-muted-foreground">({total})</span>
          )}
        </div>
      </div>

      {history.length === 0 ? (
        <div className="text-center py-8 text-muted-foreground">
          <History className="h-12 w-12 mx-auto mb-4 opacity-50" />
          <p>Aucune modification enregistrée</p>
        </div>
      ) : (
        <>
          <div className="relative">
            {/* Timeline line */}
            <div className="absolute left-6 top-0 bottom-0 w-0.5 bg-border" />

            {/* Timeline items */}
            <div className="space-y-6">
              {history.map((item) => {
                const Icon = getActionIcon(item.action);
                const actionColor = getActionColor(item.action);
                const oldValue = parseValue(item.old_value);
                const newValue = parseValue(item.new_value);

                return (
                  <div key={item.id} className="relative flex gap-4">
                    {/* Timeline dot */}
                    <div
                      className={cn(
                        'relative z-10 flex h-12 w-12 items-center justify-center rounded-full border-2 border-background',
                        actionColor,
                      )}
                    >
                      <Icon className="h-5 w-5" />
                    </div>

                    {/* Content */}
                    <div className="flex-1 space-y-2 pb-6">
                      <div className="flex items-center justify-between">
                        <div className="flex items-center gap-2">
                          <span
                            className={cn(
                              'text-sm font-semibold',
                              actionColor.split(' ')[0],
                            )}
                          >
                            {getActionLabel(item.action)}
                          </span>
                          <span className="text-xs text-muted-foreground">
                            #{item.id}
                          </span>
                        </div>
                        <div className="flex items-center gap-1 text-xs text-muted-foreground">
                          <Calendar className="h-3 w-3" />
                          <span>{formatDate(item.created_at)}</span>
                        </div>
                      </div>

                      {/* Values comparison */}
                      {(oldValue !== null || newValue !== null) && (
                        <div className="space-y-2 rounded-lg border bg-muted/50 p-3 text-sm">
                          {oldValue !== null && (
                            <div>
                              <div className="text-xs font-medium text-muted-foreground mb-1">
                                Ancienne valeur:
                              </div>
                              <pre className="text-xs bg-background rounded p-2 overflow-x-auto">
                                {formatValue(oldValue)}
                              </pre>
                            </div>
                          )}
                          {newValue !== null && (
                            <div>
                              <div className="text-xs font-medium text-muted-foreground mb-1">
                                Nouvelle valeur:
                              </div>
                              <pre className="text-xs bg-background rounded p-2 overflow-x-auto">
                                {formatValue(newValue)}
                              </pre>
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          </div>

          {/* Pagination */}
          {total > currentLimit && (
            <div className="flex items-center justify-between border-t pt-4">
              <div className="text-sm text-muted-foreground">
                Affichage {currentOffset + 1} -{' '}
                {Math.min(currentOffset + currentLimit, total)} sur {total}
              </div>
              <div className="flex gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handlePreviousPage}
                  disabled={!hasPreviousPage}
                >
                  <ChevronLeft className="h-4 w-4 mr-1" />
                  Précédent
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleNextPage}
                  disabled={!hasNextPage}
                >
                  Suivant
                  <ChevronRight className="h-4 w-4 ml-1" />
                </Button>
              </div>
            </div>
          )}
        </>
      )}
    </div>
  );
}
