'use client';

/**
 * Page admin "/admin/media" — gestionnaire central des médias.
 *
 * Listing + filtres + upload + sélection. La modale d'édition (visibilité,
 * alt, caption) est extraite dans `MediaDetailsModal.client.js` et réutilisée
 * par d'autres contextes (ex. bloc image du BlockEditor).
 */

import { registerPage } from '../../admin/registry.js';
import { useState, useEffect, useCallback, useRef } from 'react';
import { Card, Button } from '@zen/core/shared/components';
import { useToast } from '@zen/core/toast';
import { CloudUploadIcon } from '@zen/core/shared/icons';
import AdminHeader from '../../admin/components/AdminHeader.js';
import MediaGrid from '../components/MediaGrid.client.js';
import MediaFilters from '../components/MediaFilters.client.js';
import MediaDetailsModal from '../components/MediaDetailsModal.client.js';

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

const MediaPage = ({ user }) => {
  const toast = useToast();
  const fileInputRef = useRef(null);
  const canUpload = user?.permissions?.includes('media.upload');
  const canDelete = user?.permissions?.includes('media.delete');

  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);
  const [uploading, setUploading] = useState(false);
  const [filters, setFilters] = useState({ search: '', kind: '', visibility: '' });
  const [selected, setSelected] = useState(null);

  const { error: toastError } = toast;
  const fetchItems = useCallback(async () => {
    setLoading(true);
    try {
      const params = new URLSearchParams({ limit: '60' });
      if (filters.search)     params.set('search', filters.search);
      if (filters.kind)       params.set('kind', filters.kind);
      if (filters.visibility) params.set('visibility', filters.visibility);

      const response = await fetch(`${MEDIA_API}?${params}`, { credentials: 'include' });
      if (!response.ok) throw new Error(`Error ${response.status}`);
      const data = await response.json();
      setItems(data.media || []);
    } catch (err) {
      toastError(err.message || 'Échec du chargement');
    } finally {
      setLoading(false);
    }
  }, [filters, toastError]);

  useEffect(() => {
    fetchItems();
  }, [fetchItems]);

  const handleUpload = async (event) => {
    const files = Array.from(event.target.files || []);
    if (files.length === 0) return;

    setUploading(true);
    try {
      for (const file of files) {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('visibility', 'private');

        const response = await fetch(MEDIA_API, {
          method: 'POST',
          credentials: 'include',
          body: formData,
        });
        const data = await response.json();
        if (!response.ok) {
          toast.error(`${file.name} : ${data.message || 'échec'}`);
        }
      }
      toast.success(`${files.length} fichier(s) téléversé(s)`);
      await fetchItems();
    } finally {
      setUploading(false);
      if (fileInputRef.current) fileInputRef.current.value = '';
    }
  };

  return (
    <div className="flex flex-col gap-4 sm:gap-6 lg:gap-8">
      <AdminHeader
        title="Médias"
        description="Bibliothèque de fichiers utilisés dans le contenu du site."
        action={canUpload && (
          <>
            <input
              ref={fileInputRef}
              type="file"
              multiple
              onChange={handleUpload}
              className="hidden"
            />
            <Button
              variant="primary"
              icon={CloudUploadIcon}
              onClick={() => fileInputRef.current?.click()}
              loading={uploading}
            >
              Téléverser
            </Button>
          </>
        )}
      />

      <MediaFilters filters={filters} onChange={setFilters} />

      <Card variant="default">
        <MediaGrid
          items={items}
          loading={loading}
          onSelect={(media) => setSelected(media)}
          emptyMessage={
            filters.search || filters.kind || filters.visibility
              ? 'Aucun média ne correspond aux filtres'
              : 'Aucun média téléversé pour le moment'
          }
        />
      </Card>

      <MediaDetailsModal
        isOpen={!!selected}
        media={selected}
        onClose={() => setSelected(null)}
        onUpdated={(updated) => {
          setItems(prev => prev.map(m => m.id === updated.id ? updated : m));
          setSelected(updated);
        }}
        onDeleted={(id) => {
          setItems(prev => prev.filter(m => m.id !== id));
          setSelected(null);
        }}
        canDelete={canDelete}
        canEdit={canUpload}
      />
    </div>
  );
};

export default MediaPage;

registerPage({ slug: 'media', title: 'Médias', Component: MediaPage });
