import { useEffect, useState } from 'react';
import {
  listVersions,
  createVersion,
  restoreVersion,
  TrackVersion,
  TrackVersionError,
  CreateVersionRequest,
} from '../services/trackVersionService';
import { Dialog, DialogHeader, DialogBody, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { LoadingSpinner } from '@/components/ui/loading-spinner';
import { useToast } from '@/hooks/useToast';
import { History, Plus, RotateCcw, Calendar, FileText, HardDrive } from 'lucide-react';
import { cn } from '@/lib/utils';

/**
 * TrackVersionHistory Component
 * T0325: Composant pour afficher l'historique des versions d'un track, créer une nouvelle version et restaurer une version
 */

interface TrackVersionHistoryProps {
  trackId: number;
  trackFilePath?: string;
  trackFileSize?: number;
  className?: string;
}

export function TrackVersionHistory({
  trackId,
  trackFilePath,
  trackFileSize,
  className,
}: TrackVersionHistoryProps) {
  const [versions, setVersions] = useState<TrackVersion[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showCreateDialog, setShowCreateDialog] = useState(false);
  const [creating, setCreating] = useState(false);
  const [restoring, setRestoring] = useState<number | null>(null);
  const [changelog, setChangelog] = useState('');
  const [createError, setCreateError] = useState<string | null>(null);
  const { toast } = useToast();

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

  const loadVersions = async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await listVersions(trackId);
      setVersions(data);
    } catch (err) {
      if (err instanceof TrackVersionError) {
        setError(err.message);
      } else {
        setError('Impossible de charger les versions');
      }
    } finally {
      setLoading(false);
    }
  };

  const handleCreateVersion = async () => {
    if (!trackFilePath || !trackFileSize) {
      setCreateError('Informations du track manquantes');
      return;
    }

    setCreating(true);
    setCreateError(null);

    try {
      const data: CreateVersionRequest = {
        file_path: trackFilePath,
        file_size: trackFileSize,
        changelog: changelog.trim() || undefined,
      };

      await createVersion(trackId, data);
      toast.success('Version créée avec succès');
      setShowCreateDialog(false);
      setChangelog('');
      await loadVersions(); // Reload versions list
    } catch (err) {
      let errorMessage = 'Échec de la création de la version';
      if (err instanceof TrackVersionError) {
        errorMessage = err.message;
      } else if (err instanceof Error) {
        errorMessage = err.message;
      }
      setCreateError(errorMessage);
      toast.error(errorMessage);
    } finally {
      setCreating(false);
    }
  };

  const handleRestoreVersion = async (versionId: number) => {
    if (!confirm('Êtes-vous sûr de vouloir restaurer cette version ? Le fichier actuel sera remplacé.')) {
      return;
    }

    setRestoring(versionId);
    try {
      await restoreVersion(trackId, versionId);
      toast.success('Version restaurée avec succès');
      await loadVersions(); // Reload versions list
    } catch (err) {
      let errorMessage = 'Échec de la restauration de la version';
      if (err instanceof TrackVersionError) {
        errorMessage = err.message;
      } else if (err instanceof Error) {
        errorMessage = err.message;
      }
      toast.error(errorMessage);
    } finally {
      setRestoring(null);
    }
  };

  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 formatFileSize = (bytes: number): string => {
    if (bytes >= 1024 * 1024 * 1024) {
      return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
    }
    if (bytes >= 1024 * 1024) {
      return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
    }
    if (bytes >= 1024) {
      return `${(bytes / 1024).toFixed(2)} KB`;
    }
    return `${bytes} B`;
  };

  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>
    );
  }

  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 versions</h3>
          <span className="text-sm text-muted-foreground">({versions.length})</span>
        </div>
        {trackFilePath && trackFileSize && (
          <Button
            onClick={() => setShowCreateDialog(true)}
            size="sm"
            variant="outline"
            className="gap-2"
          >
            <Plus className="h-4 w-4" />
            Créer une version
          </Button>
        )}
      </div>

      {versions.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 version enregistrée</p>
          {trackFilePath && trackFileSize && (
            <p className="text-sm mt-2">Créez votre première version pour commencer</p>
          )}
        </div>
      ) : (
        <div className="space-y-3">
          {versions.map((version) => (
            <div
              key={version.id}
              className="border rounded-lg p-4 hover:bg-accent/50 transition-colors"
            >
              <div className="flex items-start justify-between">
                <div className="flex-1 space-y-2">
                  <div className="flex items-center gap-2">
                    <span className="font-semibold">Version {version.version_number}</span>
                    <span className="text-xs text-muted-foreground">#{version.id}</span>
                  </div>

                  {version.changelog && (
                    <div className="flex items-start gap-2 text-sm text-muted-foreground">
                      <FileText className="h-4 w-4 mt-0.5 flex-shrink-0" />
                      <p className="flex-1">{version.changelog}</p>
                    </div>
                  )}

                  <div className="flex flex-wrap items-center gap-4 text-xs text-muted-foreground">
                    <div className="flex items-center gap-1">
                      <Calendar className="h-3 w-3" />
                      <span>{formatDate(version.created_at)}</span>
                    </div>
                    <div className="flex items-center gap-1">
                      <HardDrive className="h-3 w-3" />
                      <span>{formatFileSize(version.file_size)}</span>
                    </div>
                  </div>
                </div>

                <Button
                  onClick={() => handleRestoreVersion(version.id)}
                  size="sm"
                  variant="outline"
                  disabled={restoring === version.id}
                  className="gap-2 ml-4"
                >
                  {restoring === version.id ? (
                    <>
                      <LoadingSpinner size="xs" />
                      Restauration...
                    </>
                  ) : (
                    <>
                      <RotateCcw className="h-4 w-4" />
                      Restaurer
                    </>
                  )}
                </Button>
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Create Version Dialog */}
      <Dialog
        open={showCreateDialog}
        onClose={() => {
          setShowCreateDialog(false);
          setChangelog('');
          setCreateError(null);
        }}
        title="Créer une nouvelle version"
        size="md"
      >
        <DialogBody>
          <div className="space-y-4">
            <div>
              <Label htmlFor="changelog">Changelog (optionnel)</Label>
              <p className="text-sm text-muted-foreground mb-2">
                Décrivez les changements apportés dans cette version
              </p>
              <Input
                id="changelog"
                value={changelog}
                onChange={(e) => setChangelog(e.target.value)}
                placeholder="Ex: Correction du mixage, ajout d'effets..."
                className="w-full"
              />
            </div>

            <div className="text-sm text-muted-foreground space-y-1">
              <p>
                <strong>Fichier:</strong> {trackFilePath}
              </p>
              <p>
                <strong>Taille:</strong> {trackFileSize ? formatFileSize(trackFileSize) : 'N/A'}
              </p>
            </div>

            {createError && (
              <Alert variant="destructive">
                <AlertDescription>{createError}</AlertDescription>
              </Alert>
            )}
          </div>
        </DialogBody>
        <DialogFooter>
          <Button
            variant="outline"
            onClick={() => {
              setShowCreateDialog(false);
              setChangelog('');
              setCreateError(null);
            }}
            disabled={creating}
          >
            Annuler
          </Button>
          <Button onClick={handleCreateVersion} disabled={creating}>
            {creating ? (
              <>
                <LoadingSpinner size="xs" className="mr-2" />
                Création...
              </>
            ) : (
              'Créer la version'
            )}
          </Button>
        </DialogFooter>
      </Dialog>
    </div>
  );
}

