import { FormEvent, useEffect, useState } from "react";
import { Play, Plus, Trash2 } from "lucide-react";
import type { JobDto, LibraryDto, UserDto } from "@readabook/shared";
import { api, getApiFallback } from "../api/client";
import { EmptyState, ErrorRibbon, LoadingState, Panel } from "../components/ui";

export function AdminPage() {
  const [libraries, setLibraries] = useState<LibraryDto[]>([]);
  const [jobs, setJobs] = useState<JobDto[]>([]);
  const [users, setUsers] = useState<UserDto[]>([]);
  const [loading, setLoading] = useState(true);
  const [name, setName] = useState("Bibliotheque locale");
  const [path, setPath] = useState("/library");
  const [error, setError] = useState<string>();
  const [success, setSuccess] = useState<string>();

  async function refresh() {
    setLoading(true);
    setError(undefined);
    const [libraryResult, jobResult, userResult] = await Promise.allSettled([api.libraries(), api.jobs(), api.users()]);
    const errors: string[] = [];

    if (libraryResult.status === "fulfilled") {
      setLibraries(libraryResult.value);
    } else {
      setLibraries(getApiFallback<LibraryDto[]>(libraryResult.reason) ?? []);
      errors.push("bibliotheques");
    }

    if (jobResult.status === "fulfilled") {
      setJobs(jobResult.value);
    } else {
      setJobs(getApiFallback<JobDto[]>(jobResult.reason) ?? []);
      errors.push("travaux");
    }

    if (userResult.status === "fulfilled") {
      setUsers(userResult.value);
    } else {
      setUsers(getApiFallback<UserDto[]>(userResult.reason) ?? []);
      errors.push("comptes");
    }

    setError(errors.length ? `Donnees admin degradees : ${errors.join(", ")}.` : undefined);
    setLoading(false);
  }

  useEffect(() => {
    void refresh();
  }, []);

  async function createLibrary(event: FormEvent) {
    event.preventDefault();
    setError(undefined);
    setSuccess(undefined);
    try {
      await api.createLibrary({ name, path, enabled: true });
      await refresh();
      setSuccess(`Bibliothèque "${name}" ajoutée.`);
    } catch (createError) {
      const fallback = getApiFallback<LibraryDto>(createError);
      if (fallback) setLibraries((current) => [fallback, ...current]);
      setError(fallback ? "Creation en mode secours, synchronisation a retenter." : "Creation impossible");
    }
  }

  async function scan(id: number) {
    setError(undefined);
    setSuccess(undefined);
    try {
      await api.scanLibrary(id);
      await refresh();
      setSuccess("Scan demandé.");
    } catch (scanError) {
      const fallback = getApiFallback<JobDto>(scanError);
      if (fallback) setJobs((current) => [fallback, ...current]);
      setError(fallback ? "Scan place en file de secours, statut a verifier." : "Scan impossible");
    }
  }

  async function deleteLibrary(library: LibraryDto) {
    const confirmed = window.confirm(
      `Supprimer la bibliothèque "${library.name}" ?\n\nLes livres restent sur le disque. ReadaBook supprimera seulement cette bibliothèque du catalogue.`
    );
    if (!confirmed) return;

    setError(undefined);
    setSuccess(undefined);
    try {
      await api.deleteLibrary(library.id);
      setLibraries((current) => current.filter((item) => item.id !== library.id));
      setSuccess(`Bibliothèque "${library.name}" supprimée. Les fichiers disque n'ont pas été supprimés.`);
    } catch (deleteError) {
      setError(deleteError instanceof Error ? deleteError.message : "Suppression impossible");
    }
  }

  return (
    <div className="page-grid">
      <Panel className="span-2">
        <div className="section-heading">
          <h1>Administration</h1>
          <span>{loading ? "chargement" : `${users.length} comptes`}</span>
        </div>
        <ErrorRibbon message={error} />
        {success && <div className="success-ribbon">{success}</div>}
        {error && (
          <div className="retry-row">
            <span>Les formulaires restent disponibles.</span>
            <button className="ghost-button" onClick={() => void refresh()}>
              Reessayer
            </button>
          </div>
        )}
        <form className="admin-form" onSubmit={createLibrary}>
          <label>
            Nom de la bibliothèque
            <input value={name} onChange={(event) => setName(event.target.value)} required />
            <small>Nom affiché dans l’application, par exemple : Romans, BD, Documentation.</small>
          </label>
          <label>
            Chemin du dossier
            <input value={path} onChange={(event) => setPath(event.target.value)} required />
            <small>Emplacement réel sur le serveur où ReadaBook lit les livres.</small>
          </label>
          <button className="primary-button" type="submit">
            <Plus size={17} />
            Ajouter
          </button>
        </form>
      </Panel>

      <Panel>
        <div className="section-heading">
          <h2>Travaux</h2>
          <span>{jobs.length}</span>
        </div>
        {loading && !jobs.length ? (
          <LoadingState label="Lecture des travaux" />
        ) : jobs.length ? (
          <div className="job-list">
            {jobs.map((job) => (
              <div key={job.id}>
                <strong>{job.type}</strong>
                <span>{job.status}</span>
              </div>
            ))}
          </div>
        ) : (
          <EmptyState title="Aucun travail" detail="Les scans apparaitront ici." />
        )}
      </Panel>

      <Panel className="span-3">
        {loading && !libraries.length ? (
          <LoadingState label="Lecture des rayons" />
        ) : libraries.length ? (
          <div className="library-table">
            {libraries.map((library) => (
              <div key={library.id}>
                <div className="library-copy">
                  <strong>{library.name}</strong>
                  <span>Chemin : {library.path}</span>
                </div>
                <span>{library.enabled ? "actif" : "pause"}</span>
                <button className="ghost-button" onClick={() => scan(library.id)}>
                  <Play size={16} />
                  Scanner
                </button>
                <button className="ghost-button danger-button" onClick={() => void deleteLibrary(library)}>
                  <Trash2 size={16} />
                  Supprimer
                </button>
              </div>
            ))}
          </div>
        ) : (
          <EmptyState title="Aucun rayon" detail="Ajoute un chemin puis relance la synchronisation." />
        )}
      </Panel>
    </div>
  );
}
