import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { getTrack, updateTrack, TrackUploadError } from '../services/trackService';
import { Track } from '../types/track';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Checkbox } from '@/components/ui/checkbox';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { LoadingSpinner } from '@/components/ui/loading-spinner';
import { Alert } from '@/components/ui/alert';
import { useToast } from '@/hooks/useToast';
import { Save, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';

/**
 * TrackEdit Component
 * T0278: Composant pour éditer les métadonnées d'un track
 */

const trackEditSchema = z.object({
  title: z.string().min(1, 'Le titre est requis'),
  artist: z.string().optional(),
  album: z.string().optional(),
  genre: z.string().optional(),
  year: z.union([z.number().int().min(1900).max(2100), z.literal('')]).optional(),
  is_public: z.boolean().default(false),
});

type TrackEditFormData = z.infer<typeof trackEditSchema>;

interface TrackEditProps {
  trackId: number;
  onSave?: (track: Track) => void;
  onCancel?: () => void;
  className?: string;
}

export function TrackEdit({ trackId, onSave, onCancel, className }: TrackEditProps) {
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const { toast } = useToast();

  const {
    register,
    handleSubmit,
    setValue,
    watch,
    formState: { errors, isDirty },
    reset,
  } = useForm<TrackEditFormData>({
    resolver: zodResolver(trackEditSchema),
    defaultValues: {
      title: '',
      artist: '',
      album: '',
      genre: '',
      year: undefined,
      is_public: false,
    },
  });

  const isPublicValue = watch('is_public');

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

  const loadTrack = async () => {
    setLoading(true);
    setError(null);
    try {
      const track = await getTrack(trackId);
      setValue('title', track.title);
      setValue('artist', track.artist || '');
      setValue('album', track.album || '');
      setValue('genre', track.genre || '');
      setValue('year', track.year || undefined);
      setValue('is_public', track.is_public);
      reset({
        title: track.title,
        artist: track.artist || '',
        album: track.album || '',
        genre: track.genre || '',
        year: track.year || undefined,
        is_public: track.is_public,
      });
    } catch (err) {
      console.error('Failed to load track:', err);
      let errorMessage = 'Impossible de charger le track';
      if (err instanceof TrackUploadError) {
        errorMessage = err.message;
      }
      setError(errorMessage);
      toast.error(errorMessage);
    } finally {
      setLoading(false);
    }
  };

  const onSubmit = async (data: TrackEditFormData) => {
    setSaving(true);
    setError(null);
    try {
      const updateParams: {
        title?: string;
        artist?: string;
        album?: string;
        genre?: string;
        year?: number;
        is_public?: boolean;
      } = {};

      if (data.title) updateParams.title = data.title;
      if (data.artist) updateParams.artist = data.artist;
      if (data.album) updateParams.album = data.album;
      if (data.genre) updateParams.genre = data.genre;
      if (data.year && data.year !== '') {
        updateParams.year = typeof data.year === 'number' ? data.year : parseInt(data.year as any);
      }
      updateParams.is_public = data.is_public;

      const updated = await updateTrack(trackId, updateParams);
      toast.success('Track mis à jour avec succès');
      onSave?.(updated);
      reset(data, { keepValues: true });
    } catch (err) {
      console.error('Failed to update track:', err);
      let errorMessage = 'Impossible de mettre à jour le track';
      if (err instanceof TrackUploadError) {
        errorMessage = err.message;
      }
      setError(errorMessage);
      toast.error(errorMessage);
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return (
      <Card className={className}>
        <CardContent className="py-8">
          <LoadingSpinner text="Chargement du track..." />
        </CardContent>
      </Card>
    );
  }

  if (error && !loading) {
    return (
      <Card className={className}>
        <CardContent className="py-8">
          <Alert variant="destructive">
            <p>{error}</p>
          </Alert>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className={className}>
      <CardHeader>
        <CardTitle>Modifier le track</CardTitle>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
          {error && (
            <Alert variant="destructive">
              <p>{error}</p>
            </Alert>
          )}

          <div className="space-y-2">
            <Label htmlFor="title">
              Titre <span className="text-destructive">*</span>
            </Label>
            <Input
              id="title"
              {...register('title')}
              placeholder="Titre du track"
              className={cn(errors.title && 'border-destructive')}
            />
            {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"
              className={cn(errors.artist && 'border-destructive')}
            />
            {errors.artist && (
              <p className="text-sm text-destructive">{errors.artist.message}</p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="album">Album</Label>
            <Input
              id="album"
              {...register('album')}
              placeholder="Nom de l'album"
              className={cn(errors.album && 'border-destructive')}
            />
            {errors.album && (
              <p className="text-sm text-destructive">{errors.album.message}</p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="genre">Genre</Label>
            <Input
              id="genre"
              {...register('genre')}
              placeholder="Genre musical"
              className={cn(errors.genre && 'border-destructive')}
            />
            {errors.genre && (
              <p className="text-sm text-destructive">{errors.genre.message}</p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="year">Année</Label>
            <Input
              id="year"
              type="number"
              {...register('year', {
                setValueAs: (v) => (v === '' ? undefined : parseInt(v, 10)),
              })}
              placeholder="Année de sortie"
              min={1900}
              max={2100}
              className={cn(errors.year && 'border-destructive')}
            />
            {errors.year && (
              <p className="text-sm text-destructive">{errors.year.message}</p>
            )}
          </div>

          <div className="flex items-center space-x-2">
            <Checkbox
              id="is_public"
              checked={isPublicValue}
              onCheckedChange={(checked) => {
                setValue('is_public', checked === true, { shouldDirty: true });
              }}
            />
            <Label
              htmlFor="is_public"
              className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
            >
              Track public
            </Label>
          </div>

          <div className="flex gap-4 pt-4">
            <Button type="submit" disabled={saving || !isDirty}>
              {saving ? (
                <>
                  <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                  Enregistrement...
                </>
              ) : (
                <>
                  <Save className="h-4 w-4 mr-2" />
                  Enregistrer
                </>
              )}
            </Button>
            {onCancel && (
              <Button type="button" variant="outline" onClick={onCancel} disabled={saving}>
                Annuler
              </Button>
            )}
          </div>
        </form>
      </CardContent>
    </Card>
  );
}

