'use client';

/**
 * Modal d'édition d'un média — réutilisable depuis n'importe quel contexte
 * (page admin Médias, bloc image du BlockEditor, …).
 *
 * Deux modes d'instanciation :
 *   - `media={media}`            : objet média déjà chargé (chemin rapide).
 *   - `slug="…"`                 : charge le média via `GET /zen/api/media/by-slug/:slug`
 *                                  (utile depuis BlockEditor où on n'a que le slug).
 *
 * Side effects : PATCH `/zen/api/media/:id` pour la sauvegarde, DELETE pour
 * la suppression. Permissions transmises par le parent via `canEdit` /
 * `canDelete` ; à défaut, lecture seule.
 */

import { useState, useEffect } from 'react';
import { Modal, Button, Input, Textarea, Select } from '@zen/core/shared/components';
import { useToast } from '@zen/core/toast';
import { Delete02Icon, Copy01Icon } from '@zen/core/shared/icons';
import MediaImage from './MediaImage.client.js';

const MEDIA_API = '/zen/api/media';

const VISIBILITY_OPTIONS = [
  { value: 'private', label: 'Privé' },
  { value: 'public',  label: 'Public' },
];

export default function MediaDetailsModal({
  isOpen,
  onClose,
  media: initialMedia = null,
  slug = null,
  onUpdated,
  onDeleted,
  canEdit = true,
  canDelete = false,
}) {
  const toast = useToast();
  const [media, setMedia]           = useState(initialMedia);
  const [loadError, setLoadError]   = useState(null);
  const [visibility, setVisibility] = useState(initialMedia?.visibility ?? 'private');
  const [altText, setAltText]       = useState(initialMedia?.alt_text || '');
  const [caption, setCaption]       = useState(initialMedia?.caption || '');
  const [referenceCount, setReferenceCount] = useState(null);
  const [saving, setSaving]     = useState(false);
  const [deleting, setDeleting] = useState(false);

  // Chargement initial : si on a déjà un média, on l'utilise. Sinon on
  // résout via le slug. Réinitialisé chaque fois que la modale s'ouvre.
  useEffect(() => {
    if (!isOpen) return;
    let cancelled = false;
    setLoadError(null);

    if (initialMedia) {
      setMedia(initialMedia);
      setVisibility(initialMedia.visibility);
      setAltText(initialMedia.alt_text || '');
      setCaption(initialMedia.caption || '');
      // Ref count en parallèle — non-bloquant pour l'affichage.
      fetch(`${MEDIA_API}/${initialMedia.id}`, { credentials: 'include' })
        .then(r => r.json())
        .then(data => { if (!cancelled) setReferenceCount(data.referenceCount ?? 0); })
        .catch(() => {});
      return () => { cancelled = true; };
    }

    if (slug) {
      fetch(`${MEDIA_API}/by-slug/${encodeURIComponent(slug)}`, { credentials: 'include' })
        .then(async r => {
          if (!r.ok) throw new Error(`Statut ${r.status}`);
          return r.json();
        })
        .then(data => {
          if (cancelled) return;
          const m = data.media ?? data;
          if (!m?.id) throw new Error('Média introuvable');
          setMedia(m);
          setVisibility(m.visibility);
          setAltText(m.alt_text || '');
          setCaption(m.caption || '');
          setReferenceCount(data.referenceCount ?? null);
        })
        .catch(err => { if (!cancelled) setLoadError(err.message || 'Échec du chargement'); });
      return () => { cancelled = true; };
    }

    setLoadError('Aucun média à afficher');
    return () => { cancelled = true; };
  }, [isOpen, initialMedia, slug]);

  const url = media ? `/zen/api/media/file/${media.slug}` : null;
  const isImage = media?.mime_type?.startsWith('image/');
  const fullUrl = (url && typeof window !== 'undefined') ? `${window.location.origin}${url}` : url;

  const handleSave = async () => {
    if (!media) return;
    setSaving(true);
    try {
      const response = await fetch(`${MEDIA_API}/${media.id}`, {
        method: 'PATCH',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ visibility, altText, caption }),
      });
      const data = await response.json();
      if (!response.ok) throw new Error(data.message || 'Échec de la mise à jour');
      toast.success('Média mis à jour');
      setMedia(data.media);
      onUpdated?.(data.media);
    } catch (err) {
      toast.error(err.message);
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!media) return;
    if (!confirm('Supprimer définitivement ce média ?')) return;
    setDeleting(true);
    try {
      const response = await fetch(`${MEDIA_API}/${media.id}`, {
        method: 'DELETE',
        credentials: 'include',
      });
      const data = await response.json();
      if (!response.ok) throw new Error(data.message || 'Échec de la suppression');
      toast.success('Média supprimé');
      onDeleted?.(media.id);
    } catch (err) {
      toast.error(err.message);
    } finally {
      setDeleting(false);
    }
  };

  const handleCopyUrl = async () => {
    if (!fullUrl) return;
    try {
      await navigator.clipboard.writeText(fullUrl);
      toast.success('URL copiée');
    } catch {
      toast.error('Impossible de copier');
    }
  };

  if (!isOpen) return null;

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title={media?.original_name ?? 'Média'}
      size="xl"
      footer={
        <div className="flex items-center justify-between">
          {canDelete && media ? (
            <Button variant="danger" icon={Delete02Icon} onClick={handleDelete} loading={deleting}>
              Supprimer
            </Button>
          ) : <div />}
          <div className="flex gap-2">
            <Button variant="ghost" onClick={onClose}>Fermer</Button>
            {canEdit && media && (
              <Button variant="primary" onClick={handleSave} loading={saving}>
                Enregistrer
              </Button>
            )}
          </div>
        </div>
      }
    >
      {loadError ? (
        <div className="p-6 text-sm text-red-600 dark:text-red-400">{loadError}</div>
      ) : !media ? (
        <div className="p-6 text-sm text-neutral-500">Chargement…</div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <div className="bg-neutral-50 dark:bg-neutral-950 rounded-lg overflow-hidden flex items-center justify-center min-h-64">
            {isImage ? (
              <MediaImage
                media={media}
                width={800}
                height={600}
                className="max-w-full max-h-96 w-auto h-auto object-contain"
                alt={altText || media.original_name}
              />
            ) : (
              <div className="text-center p-6 text-sm text-neutral-500">
                {media.mime_type}
                <br />
                <a href={url} target="_blank" rel="noreferrer" className="text-blue-500 hover:underline mt-2 inline-block">
                  Ouvrir le fichier
                </a>
              </div>
            )}
          </div>

          <div className="space-y-3">
            <div>
              <label className="block text-xs font-medium text-neutral-700 dark:text-white mb-1">URL publique</label>
              <div className="flex gap-1">
                <Input value={fullUrl ?? ''} onChange={() => {}} disabled />
                <Button variant="secondary" icon={Copy01Icon} onClick={handleCopyUrl} />
              </div>
              <p className="mt-1 text-[11px] text-neutral-500">
                {visibility === 'public' ? 'Accessible sans connexion.' : 'Privé : accessible uniquement aux utilisateurs avec la permission media.view.'}
              </p>
            </div>

            <Select
              label="Visibilité"
              value={visibility}
              onChange={setVisibility}
              options={VISIBILITY_OPTIONS}
              disabled={!canEdit}
              placeholder=""
            />

            {isImage && (
              <Input
                label="Texte alternatif"
                value={altText}
                onChange={setAltText}
                disabled={!canEdit}
                description="Décrit l'image pour les lecteurs d'écran et le SEO."
              />
            )}

            <Textarea
              label="Légende"
              value={caption}
              onChange={setCaption}
              disabled={!canEdit}
              rows={2}
            />

            <div className="text-xs text-neutral-500 dark:text-neutral-400 space-y-1 pt-2 border-t border-neutral-200 dark:border-neutral-800">
              <div>Type : <span className="text-neutral-700 dark:text-neutral-300">{media.mime_type}</span></div>
              <div>Taille : <span className="text-neutral-700 dark:text-neutral-300">{Math.round(Number(media.size_bytes) / 1024)} Ko</span></div>
              {referenceCount !== null && (
                <div>Utilisé par : <span className="text-neutral-700 dark:text-neutral-300">{referenceCount} contenu(s)</span></div>
              )}
            </div>
          </div>
        </div>
      )}
    </Modal>
  );
}
