"use client";

import { faPlus, faFolder } from "@fortawesome/free-solid-svg-icons";
import { useEffect, useState } from "react";
import Toast from "@/components/ui/Toast";
import { useAdminToast } from "@/hooks/admin/useAdminToast";
import AdminPageHeader from "@/components/admin/AdminPageHeader";
import AdminCard from "@/components/admin/AdminCard";
import AdminEmptyState from "@/components/admin/AdminEmptyState";
import AdminConfirmDialog from "@/components/admin/AdminConfirmDialog";
import AdminModal from "@/components/admin/AdminModal";
import AdminLoadingState from "@/components/admin/AdminLoadingState";
import { adminFetch } from "@/lib/adminFetch";
import ProjectForm from "./ProjectForm";
import ProjectList from "./ProjectList";

interface Project {
  id?: number;
  name: string;
  description: string;
  shortDescription?: string;
  coverImage: string;
  galleryImages: string[];
}

interface ProjectWithFiles {
  id?: number;
  name: string;
  description: string;
  shortDescription?: string;
  coverImage: string | File;
  galleryImages: (string | File)[];
}

export default function AdminProjects() {
  const [projects, setProjects] = useState<Project[]>([]);
  const [formProject, setFormProject] = useState<ProjectWithFiles | null>(null);
  const [isSaving, setIsSaving] = useState(false);
  const [loading, setLoading] = useState(true);
  const [deleteConfirm, setDeleteConfirm] = useState<{
    isOpen: boolean;
    id: number | null;
  }>({ isOpen: false, id: null });
  const { toast, showSuccess, showError, hideToast } = useAdminToast();

  useEffect(() => {
    let cancelled = false;
    fetch("/api/projects")
      .then((res) => res.json())
      .then((data) => {
        if (!cancelled) {
          setProjects(data);
          setLoading(false);
        }
      })
      .catch(() => {
        if (!cancelled) {
          showError("Failed to load projects");
          setLoading(false);
        }
      });
    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleAddClick = () => {
    setFormProject({
      name: "",
      description: "",
      shortDescription: "",
      coverImage: "",
      galleryImages: [],
    });
  };

  const handleEdit = (project: Project) => {
    setFormProject({ ...project });
  };

  const handleDelete = async (id: number) => {
    try {
      const res = await adminFetch(`/api/projects/${id}`, { method: "DELETE" });
      if (!res.ok) throw new Error();
      setProjects((prev) => prev.filter((p) => p.id !== id));
      showSuccess("Project deleted successfully!");
    } catch {
      showError("Failed to delete project. Please try again.");
    } finally {
      setDeleteConfirm({ isOpen: false, id: null });
    }
  };

  const handleSave = async (project: ProjectWithFiles) => {
    setIsSaving(true);
    try {
      let coverImageUrl = "";
      if (project.coverImage && typeof project.coverImage !== "string") {
        const coverForm = new FormData();
        coverForm.append("file", project.coverImage);
        const res = await adminFetch("/api/upload", { method: "POST", body: coverForm });
        if (!res.ok) throw new Error();
        const { url } = await res.json();
        coverImageUrl = url;
      } else {
        coverImageUrl = project.coverImage as string;
      }

      const galleryUrls: string[] = [];
      for (const img of project.galleryImages) {
        if (typeof img !== "string") {
          const form = new FormData();
          form.append("file", img);
          const res = await adminFetch("/api/upload", { method: "POST", body: form });
          if (!res.ok) throw new Error();
          const { url } = await res.json();
          galleryUrls.push(url);
        } else {
          galleryUrls.push(img);
        }
      }

      const formData = new FormData();
      formData.append("name", project.name);
      formData.append("description", project.description);
      formData.append("shortDescription", project.shortDescription || "");
      formData.append("coverImage", coverImageUrl);

      if (project.id) {
        galleryUrls.forEach((url) => formData.append("galleryImages[]", url));
        const res = await adminFetch(`/api/projects/${project.id}`, {
          method: "PUT",
          body: formData,
        });
        if (!res.ok) throw new Error();
        const updated = await res.json();
        setProjects((prev) => prev.map((p) => (p.id === updated.id ? updated : p)));
        showSuccess("Project updated successfully!");
      } else {
        galleryUrls.forEach((url) => formData.append("galleryImages", url));
        const res = await adminFetch("/api/projects", { method: "POST", body: formData });
        if (!res.ok) throw new Error();
        const created = await res.json();
        setProjects((prev) => [...prev, created]);
        showSuccess("Project saved successfully!");
      }
      setFormProject(null);
    } catch {
      showError("Failed to save project. Please try again.");
    } finally {
      setIsSaving(false);
    }
  };

  return (
    <>
      {toast && <Toast message={toast.message} type={toast.type} onClose={hideToast} />}

      <AdminConfirmDialog
        isOpen={deleteConfirm.isOpen}
        onClose={() => setDeleteConfirm({ isOpen: false, id: null })}
        onConfirm={() => deleteConfirm.id && handleDelete(deleteConfirm.id)}
        title="Delete project"
        message="Are you sure you want to delete this project? This action cannot be undone."
      />

      <AdminPageHeader
        title="Projects"
        description="Manage your portfolio projects"
        action={{
          label: "Add project",
          onClick: handleAddClick,
          icon: faPlus,
          variant: "primary",
        }}
      />

      <AdminCard>
        {loading ? (
          <AdminLoadingState message="Loading projects..." />
        ) : projects.length === 0 ? (
          <AdminEmptyState
            title="No projects yet"
            description="Add your first project to showcase your work"
            icon={faFolder}
            action={{ label: "Add project", onClick: handleAddClick }}
          />
        ) : (
          <ProjectList
            projects={projects}
            onEdit={handleEdit}
            onDelete={(id) => setDeleteConfirm({ isOpen: true, id })}
          />
        )}
      </AdminCard>

      <AdminModal
        isOpen={!!formProject}
        onClose={() => !isSaving && setFormProject(null)}
        title={formProject?.id ? "Edit project" : "Add new project"}
        size="xl"
      >
        {formProject && (
          <ProjectForm
            initialProject={formProject}
            onSave={handleSave}
            onCancel={() => setFormProject(null)}
            isSaving={isSaving}
          />
        )}
      </AdminModal>
    </>
  );
}
