/**
 * Composant PlaylistForm
 * T0461: Create Playlist Create/Edit Form
 */

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import { Loader2 } from 'lucide-react';
import { useCreatePlaylist, useUpdatePlaylist } from '../hooks/usePlaylist';
import { useToast } from '@/hooks/useToast';
import { useIsRateLimited } from '@/hooks/useIsRateLimited';
import type {
  Playlist,
  CreatePlaylistRequest,
  UpdatePlaylistRequest,
} from '../types';

// Schéma de validation
const playlistFormSchema = z.object({
  title: z
    .string()
    .min(1, 'Le titre est requis')
    .max(200, 'Le titre ne peut pas dépasser 200 caractères'),
  description: z
    .string()
    .max(2000, 'La description ne peut pas dépasser 2000 caractères')
    .optional()
    .or(z.literal('')),
  is_public: z.boolean().default(true),
  cover_url: z
    .string()
    .optional()
    .refine((val) => !val || val === '' || val.length <= 500, {
      message: "L'URL ne peut pas dépasser 500 caractères",
    })
    .refine(
      (val) => {
        if (!val || val === '') return true;
        try {
          new URL(val);
          return true;
        } catch {
          return false;
        }
      },
      {
        message: "L'URL de la couverture doit être valide",
      },
    )
    .transform((val) => (val === '' ? undefined : val)),
});

type PlaylistFormData = z.infer<typeof playlistFormSchema>;

interface PlaylistFormProps {
  playlist?: Playlist;
  onSubmit?: (
    data: CreatePlaylistRequest | UpdatePlaylistRequest,
  ) => void | Promise<void>;
  onCancel?: () => void;
  submitLabel?: string;
  className?: string;
}

export function PlaylistForm({
  playlist,
  onSubmit,
  onCancel,
  submitLabel,
  className,
}: PlaylistFormProps) {
  const { success: showSuccess, error: showError } = useToast();
  const createMutation = useCreatePlaylist();
  const updateMutation = useUpdatePlaylist();
  const isRateLimited = useIsRateLimited();

  const isEditMode = !!playlist;
  const isSubmitting = createMutation.isPending || updateMutation.isPending;

  const {
    register,
    handleSubmit,
    formState: { errors },
    watch,
  } = useForm<PlaylistFormData>({
    resolver: zodResolver(playlistFormSchema),
    defaultValues: {
      title: playlist?.title || '',
      description: playlist?.description || '',
      is_public: playlist?.is_public ?? true,
      cover_url: playlist?.cover_url || '',
    },
  });

  const isPublic = watch('is_public');

  const handleFormSubmit = async (data: PlaylistFormData) => {
    try {
      const formData: CreatePlaylistRequest | UpdatePlaylistRequest = {
        title: data.title,
        description: data.description || undefined,
        is_public: data.is_public,
        cover_url: data.cover_url || undefined,
      };

      if (onSubmit) {
        await onSubmit(formData);
      } else if (isEditMode && playlist) {
        await updateMutation.mutateAsync({
          id: playlist.id,
          data: formData as UpdatePlaylistRequest,
        });
        showSuccess('Playlist mise à jour avec succès');
      } else {
        await createMutation.mutateAsync(formData as CreatePlaylistRequest);
        showSuccess('Playlist créée avec succès');
      }
    } catch (error) {
      showError(
        error instanceof Error ? error.message : 'Une erreur est survenue',
      );
    }
  };

  return (
    <form
      onSubmit={handleSubmit(handleFormSubmit)}
      className={className}
      aria-label={
        isEditMode
          ? 'Formulaire de modification de playlist'
          : 'Formulaire de création de playlist'
      }
    >
      <div className="space-y-4">
        {/* Title */}
        <div className="space-y-2">
          <Label htmlFor="title">
            Titre{' '}
            <span className="text-destructive" aria-hidden="true">
              *
            </span>
          </Label>
          <Input
            id="title"
            {...register('title')}
            placeholder="Ma playlist"
            disabled={isSubmitting}
            aria-invalid={errors.title ? 'true' : 'false'}
            aria-describedby={errors.title ? 'title-error' : undefined}
            aria-required="true"
          />
          {errors.title && (
            <p
              id="title-error"
              className="text-sm text-destructive"
              role="alert"
            >
              {errors.title.message}
            </p>
          )}
        </div>

        {/* Description */}
        <div className="space-y-2">
          <Label htmlFor="description">Description</Label>
          <Textarea
            id="description"
            {...register('description')}
            placeholder="Décrivez votre playlist..."
            rows={4}
            disabled={isSubmitting}
            aria-invalid={errors.description ? 'true' : 'false'}
            aria-describedby={
              errors.description ? 'description-error' : undefined
            }
          />
          {errors.description && (
            <p
              id="description-error"
              className="text-sm text-destructive"
              role="alert"
            >
              {errors.description.message}
            </p>
          )}
        </div>

        {/* Cover URL */}
        <div className="space-y-2">
          <Label htmlFor="cover_url">URL de la couverture</Label>
          <Input
            id="cover_url"
            type="url"
            {...register('cover_url')}
            placeholder="https://example.com/cover.jpg"
            disabled={isSubmitting}
            aria-invalid={errors.cover_url ? 'true' : 'false'}
            aria-describedby={errors.cover_url ? 'cover_url-error' : undefined}
          />
          {errors.cover_url && (
            <p
              id="cover_url-error"
              className="text-sm text-destructive"
              role="alert"
            >
              {errors.cover_url.message}
            </p>
          )}
        </div>

        {/* Is Public */}
        <div className="flex items-center space-x-2">
          <Checkbox
            id="is_public"
            {...register('is_public')}
            checked={isPublic}
            disabled={isSubmitting}
            aria-checked={isPublic}
          />
          <Label htmlFor="is_public" className="cursor-pointer">
            Playlist publique
          </Label>
        </div>

        {/* Actions */}
        <div className="flex justify-end gap-2 pt-4">
          {onCancel && (
            <Button
              type="button"
              variant="outline"
              onClick={onCancel}
              disabled={isSubmitting}
              aria-label="Annuler la modification"
            >
              Annuler
            </Button>
          )}
          <Button
            type="submit"
            disabled={isSubmitting || isRateLimited}
            aria-label={
              submitLabel ||
              (isEditMode
                ? 'Enregistrer les modifications'
                : 'Créer la playlist')
            }
          >
            {isSubmitting && (
              <Loader2
                className="w-4 h-4 mr-2 animate-spin"
                aria-hidden="true"
              />
            )}
            {submitLabel || (isEditMode ? 'Enregistrer' : 'Créer')}
          </Button>
        </div>
      </div>
    </form>
  );
}
