// CRITICAL FIX: Import React FIRST to ensure it's available
import { useState, useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
// TEMPORARY FIX: Comment out react-hook-form to isolate initialization error
// import { useForm } from 'react-hook-form';
import { Dialog, DialogBody, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Progress } from '@/components/ui/progress';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Alert } from '@/components/ui/alert';
import {
  Upload,
  X,
  FileAudio,
  AlertCircle,
  CheckCircle2,
  RefreshCw,
} from 'lucide-react';
import { tracksApi, type TrackMetadata } from '@/services/api/tracks';
import { useQueryClient } from '@tanstack/react-query';
import { LIBRARY_KEYS } from '@/features/library/hooks/useMyTracks';
import { logger } from '@/utils/logger';
import { useIsRateLimited } from '@/hooks/useIsRateLimited';

export interface UploadModalProps {
  open: boolean;
  onClose: () => void;
}

const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 MB
const ACCEPTED_AUDIO_TYPES = {
  'audio/mpeg': ['.mp3'],
  'audio/wav': ['.wav'],
  'audio/ogg': ['.ogg'],
  'audio/flac': ['.flac'],
  'audio/mp4': ['.m4a'],
  'audio/aac': ['.aac'],
};

type UploadFormData = {
  file: File | null;
  title: string;
  artist: string;
  album: string;
  genre: string;
};

const MAX_RETRY_ATTEMPTS = 3;

export function UploadModal({ open, onClose }: UploadModalProps) {
  const [file, setFile] = useState<File | null>(null);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [isUploading, setIsUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [errorCode, setErrorCode] = useState<string | null>(null);
  const [isRetryable, setIsRetryable] = useState(false);
  const [retryCount, setRetryCount] = useState(0);
  const [success, setSuccess] = useState(false);
  const isRateLimited = useIsRateLimited();

  const queryClient = useQueryClient();

  // TEMPORARY FIX: Replace useForm with useState to isolate react-hook-form initialization error
  const [formData, setFormData] = useState<UploadFormData>({
    file: null,
    title: '',
    artist: '',
    album: '',
    genre: '',
  });
  const [formErrors, setFormErrors] = useState<Partial<Record<keyof UploadFormData, string>>>({});

  // Mock functions to replace useForm methods
  const register = (name: keyof UploadFormData) => ({
    value: formData[name],
    onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
      setFormData(prev => ({ ...prev, [name]: e.target.value }));
    },
  });
  const setValue = (name: keyof UploadFormData, value: any) => {
    setFormData(prev => ({ ...prev, [name]: value }));
  };
  const getValues = () => formData;
  const reset = () => {
    setFormData({ file: null, title: '', artist: '', album: '', genre: '' });
    setFormErrors({});
  };
  const handleSubmit = (onValid: (data: UploadFormData) => void, onInvalid?: (errors: any) => void) => {
    return (e: React.FormEvent) => {
      e.preventDefault();
      // Simple validation
      if (!formData.file) {
        setFormErrors({ file: 'Veuillez sélectionner un fichier' });
        onInvalid?.({ file: { message: 'Veuillez sélectionner un fichier' } });
        return;
      }
      setFormErrors({});
      onValid(formData);
    };
  };
  const errors = formErrors;

  // ORIGINAL CODE (commented for debugging):
  // const {
  //   register,
  //   handleSubmit,
  //   setValue,
  //   getValues,
  //   formState: { errors },
  //   reset,
  // } = useForm<UploadFormData>({
  //   defaultValues: {
  //     file: null,
  //     title: '',
  //     artist: '',
  //     album: '',
  //     genre: '',
  //   },
  // });

  const onDrop = useCallback(
    (acceptedFiles: File[]) => {
      const selectedFile = acceptedFiles[0];
      if (selectedFile) {
        setFile(selectedFile);
        setError(null);
        setSuccess(false);
        // Mettre à jour le formulaire avec setValue pour que react-hook-form connaisse le fichier
        setValue('file', selectedFile, { shouldValidate: true });
        // Pré-remplir le titre avec le nom du fichier (sans extension)
        const fileNameWithoutExt = selectedFile.name.replace(/\.[^/.]+$/, '');
        // Lecture à la demande avec getValues, pas de re-render
        const currentTitle = getValues('title');
        if (!currentTitle) {
          setValue('title', fileNameWithoutExt, { shouldValidate: true });
        }
      }
    },
    [setValue, getValues],
  );

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: ACCEPTED_AUDIO_TYPES,
    maxSize: MAX_FILE_SIZE,
    multiple: false,
    onError: (err) => {
      setError(`Erreur lors de la sélection du fichier: ${err.message}`);
    },
    onDropRejected: (fileRejections) => {
      const rejection = fileRejections[0];
      if (rejection.errors[0]?.code === 'file-too-large') {
        setError('Le fichier est trop volumineux (max 100 MB)');
      } else if (rejection.errors[0]?.code === 'file-invalid-type') {
        setError(
          'Format de fichier non supporté. Formats acceptés: MP3, WAV, OGG, FLAC, M4A, AAC',
        );
      } else {
        setError(
          rejection.errors[0]?.message ||
            'Erreur lors de la sélection du fichier',
        );
      }
    },
  });

  const performUpload = useCallback(
    async (data: UploadFormData, attemptNumber: number = 1) => {
      if (!data.file) {
        setError('Veuillez sélectionner un fichier');
        setErrorCode(null);
        setIsRetryable(false);
        return;
      }

      setIsUploading(true);
      setError(null);
      setErrorCode(null);
      setIsRetryable(false);
      setSuccess(false);
      setUploadProgress(0);

      try {
        const trackMetadata: TrackMetadata = {
          title: data.title || data.file.name.replace(/\.[^/.]+$/, ''),
          artist: data.artist,
          album: data.album,
          genre: data.genre,
          is_public: false,
        };

        await tracksApi.create(data.file, trackMetadata, (progress) => {
          setUploadProgress(progress);
        });

        setSuccess(true);
        setUploadProgress(100);
        setRetryCount(0);

        // Invalider les queries pour rafraîchir la liste
        queryClient.invalidateQueries({ queryKey: LIBRARY_KEYS.all });
        queryClient.invalidateQueries({ queryKey: ['tracks'] });

        // Fermer après 1.5 secondes
        setTimeout(() => {
          handleClose();
        }, 1500);
      } catch (err) {
        let errorMessage = "Erreur lors de l'upload";
        let errorCodeValue: string | null = null;
        let retryable = false;

        if (err instanceof Error) {
          errorMessage = err.message;

          // Détecter les erreurs réseau qui sont généralement retryables
          const isNetworkError =
            errorMessage.toLowerCase().includes('network') ||
            errorMessage.toLowerCase().includes('réseau') ||
            errorMessage.toLowerCase().includes('timeout') ||
            errorMessage.toLowerCase().includes('econnaborted') ||
            errorMessage.toLowerCase().includes('etimedout') ||
            errorMessage.toLowerCase().includes('se connecter');

          // Détecter les erreurs serveur qui peuvent être retryables
          const isServerError =
            errorMessage.toLowerCase().includes('serveur') ||
            errorMessage.toLowerCase().includes('server') ||
            errorMessage.toLowerCase().includes('500') ||
            errorMessage.toLowerCase().includes('503') ||
            errorMessage.toLowerCase().includes('502');

          // Les erreurs de validation ne sont pas retryables
          const isValidationError =
            errorMessage.toLowerCase().includes('format') ||
            errorMessage.toLowerCase().includes('taille') ||
            errorMessage.toLowerCase().includes('invalide') ||
            errorMessage.toLowerCase().includes('trop volumineux') ||
            errorMessage.toLowerCase().includes('non supporté') ||
            errorMessage.toLowerCase().includes('400') ||
            errorMessage.toLowerCase().includes('413') ||
            errorMessage.toLowerCase().includes('415');

          if (isNetworkError) {
            errorCodeValue = 'NETWORK';
            retryable = attemptNumber < MAX_RETRY_ATTEMPTS;
          } else if (isServerError) {
            errorCodeValue = 'SERVER';
            retryable = attemptNumber < MAX_RETRY_ATTEMPTS;
          } else if (isValidationError) {
            errorCodeValue = 'VALIDATION';
            retryable = false;
          }
        }

        setError(errorMessage);
        setErrorCode(errorCodeValue);
        setIsRetryable(retryable);
        setUploadProgress(0);
        setRetryCount(attemptNumber);
      } finally {
        setIsUploading(false);
      }
    },
    [queryClient],
  );

  const onSubmit = useCallback(
    async (data: UploadFormData) => {
      await performUpload(data, 1);
    },
    [performUpload],
  );

  const handleRetry = useCallback(() => {
    const formData = getValues();
    const nextAttempt = retryCount + 1;
    performUpload(formData, nextAttempt);
  }, [retryCount, getValues, performUpload]);

  const handleClose = () => {
    if (!isUploading) {
      setFile(null);
      setUploadProgress(0);
      setError(null);
      setErrorCode(null);
      setIsRetryable(false);
      setRetryCount(0);
      setSuccess(false);
      reset();
      onClose();
    }
  };

  const handleRemoveFile = () => {
    setFile(null);
    setError(null);
    setSuccess(false);
    setUploadProgress(0);
    setValue('file', null, { shouldValidate: true });
  };

  return (
    <Dialog
      open={open}
      onClose={handleClose}
      title="Uploader un fichier audio"
      size="lg"
    >
      <form
        id="upload-track-form"
        onSubmit={handleSubmit(onSubmit, (errors) => {
          logger.warn('Form validation errors:', { errors });
        })}
      >
        <DialogBody>
          <div className="space-y-6">
            {/* Zone de Drag & Drop */}
            {!file ? (
              <div
                {...getRootProps()}
                className={`
                border-2 border-dashed rounded-lg p-12 text-center cursor-pointer
                transition-colors
                ${isDragActive ? 'border-primary bg-primary/5' : 'border-muted-foreground/25'}
                hover:border-primary hover:bg-primary/5
              `}
              >
                <input {...getInputProps()} />
                <FileAudio className="mx-auto h-12 w-12 text-muted-foreground mb-4" />
                <p className="text-lg font-medium mb-2">
                  {isDragActive
                    ? 'Déposez le fichier ici'
                    : 'Glissez-déposez un fichier audio'}
                </p>
                <p className="text-sm text-muted-foreground mb-4">
                  ou cliquez pour sélectionner
                </p>
                <p className="text-xs text-muted-foreground">
                  Formats acceptés: MP3, WAV, OGG, FLAC, M4A, AAC (max 100 MB)
                </p>
              </div>
            ) : (
              <div
                className="border rounded-lg p-4"
                data-testid="upload-file-display"
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-3">
                    <FileAudio className="h-8 w-8 text-primary" />
                    <div>
                      <p className="font-medium" data-testid="upload-file-name">
                        {file.name}
                      </p>
                      <p className="text-sm text-muted-foreground">
                        {(file.size / 1024 / 1024).toFixed(2)} MB
                      </p>
                    </div>
                  </div>
                  {!isUploading && (
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      onClick={handleRemoveFile}
                      className="h-8 w-8"
                    >
                      <X className="h-4 w-4" />
                    </Button>
                  )}
                </div>
              </div>
            )}

            {/* Progress Bar */}
            {isUploading && (
              <div className="space-y-2">
                <div className="flex items-center justify-between text-sm">
                  <span>Upload en cours...</span>
                  <span>{uploadProgress}%</span>
                </div>
                <Progress value={uploadProgress} />
              </div>
            )}

            {/* Messages d'erreur */}
            {error && (
              <Alert variant="destructive" data-testid="upload-error">
                <div className="flex items-start gap-3">
                  <AlertCircle className="h-4 w-4 mt-0.5 shrink-0" />
                  <div className="flex-1 space-y-2">
                    <div>
                      <p className="font-medium">{error}</p>
                      {errorCode && (
                        <p className="text-xs text-muted-foreground mt-1">
                          Code d'erreur: {errorCode}
                        </p>
                      )}
                      {retryCount > 0 && (
                        <p className="text-xs text-muted-foreground mt-1">
                          Tentative {retryCount}/{MAX_RETRY_ATTEMPTS}
                        </p>
                      )}
                    </div>
                    {isRetryable && (
                      <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={handleRetry}
                        disabled={isUploading}
                        className="mt-2"
                      >
                        <RefreshCw className="h-4 w-4 mr-2" />
                        Réessayer
                      </Button>
                    )}
                  </div>
                </div>
              </Alert>
            )}

            {/* Message de succès */}
            {success && (
              <Alert className="bg-green-50 border-green-200 text-green-800">
                <CheckCircle2 className="h-4 w-4" />
                <span>Fichier uploadé avec succès !</span>
              </Alert>
            )}

            {/* Formulaire de métadonnées */}
            {file && !isUploading && !success && (
              <div className="space-y-4 border-t pt-4">
                <h3 className="font-medium">Métadonnées (optionnel)</h3>
                <div className="grid grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label htmlFor="title">Titre *</Label>
                    <Input
                      id="title"
                      {...register('title')}
                      placeholder="Titre du morceau"
                    />
                    {errors.title && (
                      <p className="text-sm text-destructive">
                        {errors.title.message}
                      </p>
                    )}
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="artist">Artiste</Label>
                    <Input
                      id="artist"
                      {...register('artist')}
                      placeholder="Nom de l'artiste"
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="album">Album</Label>
                    <Input
                      id="album"
                      {...register('album')}
                      placeholder="Nom de l'album"
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="genre">Genre</Label>
                    <Input
                      id="genre"
                      {...register('genre')}
                      placeholder="Genre musical"
                    />
                  </div>
                </div>
              </div>
            )}
          </div>
        </DialogBody>
        <DialogFooter>
          <Button
            variant="outline"
            onClick={handleClose}
            disabled={isUploading}
            type="button"
          >
            {success ? 'Fermer' : 'Annuler'}
          </Button>
          {!success && (
            <Button
              type="submit"
              form="upload-track-form"
              disabled={!file || isUploading || isRateLimited}
              className="gap-2"
            >
              <Upload className="h-4 w-4" />
              {isUploading ? 'Upload en cours...' : 'Uploader'}
            </Button>
          )}
        </DialogFooter>
      </form>
    </Dialog>
  );
}
