import { useEffect, useMemo, useRef, useState } from "react";
import { adminApi, adminEndpoints } from "../api";
import type { ComponentRecord } from "../types";
import { Archive, Copy, Grid3X3, List, Search } from "lucide-react";
import { getBlockComponent } from "@/components/page-blocks";
import { notifyComponentLibraryUpdated } from "@/lib/componentDefaults";
import { resolvePreviewContent } from "@/lib/contentPlaceholders";
import { copyTextToClipboard } from "@/lib/clipboard";
import { filterComponentsBySearch } from "../lib/componentSearch";
import ComponentAccordionItem from "../components/ComponentAccordionItem";
import ComponentSearchBar from "../components/ComponentSearchBar";
import ComponentPreviewMini from "../components/ComponentPreviewMini";
import ComponentGuideInfo, { ComponentDisplayTitle } from "../components/ComponentGuideInfo";
import SimilarComponentsCompare from "../components/SimilarComponentsCompare";
import { getActiveComparisonGroups } from "../lib/componentCatalog";

type ViewMode = "list" | "grid";

export default function ComponentsList() {
  const [components, setComponents] = useState<ComponentRecord[]>([]);
  const [loading, setLoading] = useState(true);
  const [copyId, setCopyId] = useState<number | null>(null);
  const [archivingId, setArchivingId] = useState<number | null>(null);
  const [error, setError] = useState("");
  const [expandedIds, setExpandedIds] = useState<Set<number>>(new Set());
  const [search, setSearch] = useState("");
  const [viewMode, setViewMode] = useState<ViewMode>("list");
  const hasInitializedExpanded = useRef(false);

  const filtered = useMemo(
    () => filterComponentsBySearch(components, search),
    [components, search],
  );

  const hasActiveSearch = search.trim().length > 0;
  const comparisonGroups = useMemo(() => getActiveComparisonGroups(filtered), [filtered]);

  const load = async () => {
    setLoading(true);
    try {
      const data = await adminApi.get<{ components: ComponentRecord[] }>(adminEndpoints.components);
      const nextComponents = data.components ?? [];
      setComponents(nextComponents);
      setExpandedIds((prev) => {
        const allIds = new Set(nextComponents.map((component) => component.id));
        if (!hasInitializedExpanded.current) {
          hasInitializedExpanded.current = true;
          return allIds;
        }

        const next = new Set<number>();
        prev.forEach((id) => {
          if (allIds.has(id)) next.add(id);
        });
        return next;
      });
    } catch {
      setComponents([]);
      setExpandedIds(new Set());
    } finally {
      setLoading(false);
    }
  };

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

  const copyComponent = async (c: ComponentRecord) => {
    const payload = {
      componentId: c.id,
      componentName: c.name,
      componentSlug: c.slug,
      content: c.content ?? {},
    };
    try {
      await copyTextToClipboard(JSON.stringify(payload));
      setCopyId(c.id);
      setTimeout(() => setCopyId(null), 2000);
    } catch {
      setError("Could not copy component to clipboard. Please try again.");
      setTimeout(() => setError(""), 4000);
    }
  };

  const archiveComponent = async (c: ComponentRecord) => {
    setArchivingId(c.id);
    setError("");
    try {
      await adminApi.post(adminEndpoints.componentArchive(c.id), {});
      notifyComponentLibraryUpdated();
      await load();
    } catch {
      setError("Failed to archive component.");
      setTimeout(() => setError(""), 4000);
    } finally {
      setArchivingId(null);
    }
  };

  const toggleComponent = (id: number) => {
    setExpandedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const expandAll = () => {
    setExpandedIds(new Set(filtered.map((component) => component.id)));
  };

  const collapseAll = () => {
    setExpandedIds(new Set());
  };

  const renderActions = (c: ComponentRecord) => (
    <>
      <button
        type="button"
        onClick={() => copyComponent(c)}
        title="Copy component JSON — paste in Page editor (Paste from clipboard or Paste JSON)"
        style={{
          display: "inline-flex",
          alignItems: "center",
          gap: 8,
          padding: "8px 14px",
          border: "1px solid #e2e8f0",
          borderRadius: 8,
          background: "#fff",
          cursor: "pointer",
          fontWeight: 500,
        }}
      >
        <Copy size={18} />
        {copyId === c.id ? " Copied!" : " Copy"}
      </button>
      <button
        type="button"
        onClick={() => archiveComponent(c)}
        disabled={archivingId === c.id}
        title="Archive component"
        style={{
          display: "inline-flex",
          alignItems: "center",
          gap: 8,
          padding: "8px 14px",
          border: "1px solid #e2e8f0",
          borderRadius: 8,
          background: "#fff",
          cursor: archivingId === c.id ? "not-allowed" : "pointer",
          fontWeight: 500,
          opacity: archivingId === c.id ? 0.7 : 1,
        }}
      >
        <Archive size={18} />
        {archivingId === c.id ? " Archiving…" : " Archive"}
      </button>
    </>
  );

  const renderPreview = (c: ComponentRecord) => {
    const BlockComp = getBlockComponent(c.slug);
    if (!BlockComp) return <span className="text-muted-foreground text-sm italic">No preview</span>;
    return (
      <BlockComp
        content={resolvePreviewContent((c.content ?? {}) as Record<string, unknown>, { blockSlug: c.slug })}
      />
    );
  };

  return (
    <div>
      <div style={{ marginBottom: 24 }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
          <h1 style={{ margin: 0, fontSize: 28, fontWeight: 700 }}>Components</h1>
          {!loading && components.length > 0 && (
            <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
              <div style={{ display: "inline-flex", border: "1px solid #e2e8f0", borderRadius: 8, overflow: "hidden" }}>
                <button
                  type="button"
                  onClick={() => setViewMode("list")}
                  title="List view"
                  style={{
                    display: "inline-flex",
                    alignItems: "center",
                    gap: 6,
                    padding: "8px 12px",
                    border: "none",
                    background: viewMode === "list" ? "#0f172a" : "#fff",
                    color: viewMode === "list" ? "#fff" : "#475569",
                    cursor: "pointer",
                    fontSize: 13,
                    fontWeight: 500,
                  }}
                >
                  <List size={16} /> List
                </button>
                <button
                  type="button"
                  onClick={() => setViewMode("grid")}
                  title="Grid view"
                  style={{
                    display: "inline-flex",
                    alignItems: "center",
                    gap: 6,
                    padding: "8px 12px",
                    border: "none",
                    borderLeft: "1px solid #e2e8f0",
                    background: viewMode === "grid" ? "#0f172a" : "#fff",
                    color: viewMode === "grid" ? "#fff" : "#475569",
                    cursor: "pointer",
                    fontSize: 13,
                    fontWeight: 500,
                  }}
                >
                  <Grid3X3 size={16} /> Grid
                </button>
              </div>
              {viewMode === "list" && filtered.length > 0 && (
                <>
                  <button
                    type="button"
                    onClick={expandAll}
                    style={{
                      display: "inline-flex",
                      alignItems: "center",
                      padding: "8px 14px",
                      border: "1px solid #e2e8f0",
                      borderRadius: 8,
                      background: "#fff",
                      cursor: "pointer",
                      fontWeight: 500,
                    }}
                  >
                    Expand All
                  </button>
                  <button
                    type="button"
                    onClick={collapseAll}
                    style={{
                      display: "inline-flex",
                      alignItems: "center",
                      padding: "8px 14px",
                      border: "1px solid #e2e8f0",
                      borderRadius: 8,
                      background: "#fff",
                      cursor: "pointer",
                      fontWeight: 500,
                    }}
                  >
                    Collapse All
                  </button>
                </>
              )}
            </div>
          )}
        </div>
        <p style={{ color: "#64748b", margin: "8px 0 0", fontSize: 14 }}>Home page sections. Copy to use in Pages.</p>
      </div>
      {error && (
        <div style={{ marginBottom: 12, padding: "10px 12px", borderRadius: 10, background: "#fef2f2", border: "1px solid #fecaca", color: "#b91c1c", fontSize: 13 }}>
          {error}
        </div>
      )}
      {loading ? (
        <p style={{ color: "#64748b" }}>Loading...</p>
      ) : components.length === 0 ? (
        <div style={{ background: "#f8fafc", padding: 32, borderRadius: 12, textAlign: "center", color: "#64748b" }}>
          <p style={{ margin: 0 }}>No components. Run: php artisan db:seed --class=ComponentSeeder</p>
        </div>
      ) : (
        <>
          <ComponentSearchBar
            value={search}
            onChange={setSearch}
            totalCount={components.length}
            filteredCount={filtered.length}
          />
          {comparisonGroups.includes("whole-child-portrait") && (
            <SimilarComponentsCompare components={filtered} />
          )}
          {filtered.length === 0 ? (
            <div style={{ background: "#f8fafc", padding: 48, borderRadius: 12, textAlign: "center", color: "#64748b" }}>
              <Search size={32} style={{ color: "#cbd5e1", marginBottom: 12 }} />
              <p style={{ margin: "0 0 8px", fontSize: 16, fontWeight: 600, color: "#475569" }}>No components found</p>
              <p style={{ margin: 0, fontSize: 14 }}>Try a different search term.</p>
              {hasActiveSearch && (
                <button
                  type="button"
                  onClick={() => setSearch("")}
                  style={{
                    marginTop: 16,
                    padding: "9px 16px",
                    background: "#fff",
                    border: "1px solid #e2e8f0",
                    borderRadius: 10,
                    cursor: "pointer",
                    fontWeight: 500,
                    fontSize: 14,
                    color: "#334155",
                  }}
                >
                  Clear search
                </button>
              )}
            </div>
          ) : viewMode === "list" ? (
            <div style={{ display: "grid", gap: 12 }}>
              {filtered.map((c) => (
                <ComponentAccordionItem
                  key={c.id}
                  component={c}
                  isExpanded={expandedIds.has(c.id)}
                  onToggle={() => toggleComponent(c.id)}
                  actions={renderActions(c)}
                  preview={renderPreview(c)}
                />
              ))}
            </div>
          ) : (
            <div
              style={{
                display: "grid",
                gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))",
                gap: 16,
              }}
            >
              {filtered.map((c) => (
                <div
                  key={c.id}
                  style={{
                    display: "flex",
                    flexDirection: "column",
                    gap: 12,
                    padding: 14,
                    background: "#fff",
                    borderRadius: 12,
                    boxShadow: "0 1px 3px rgba(0,0,0,0.08)",
                    border: "1px solid #e2e8f0",
                  }}
                >
                  <ComponentPreviewMini component={c} scale={0.3} maxHeight={130} />
                  <div>
                    <ComponentDisplayTitle component={c} as="div" style={{ fontWeight: 600, fontSize: 15, color: "#0f172a" }} />
                    <div style={{ color: "#64748b", fontSize: 13, marginTop: 4 }}>
                      {c.slug}
                      {c.category ? ` · ${c.category}` : ""}
                    </div>
                    <ComponentGuideInfo component={c} variant="compact" />
                  </div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: "auto" }}>{renderActions(c)}</div>
                </div>
              ))}
            </div>
          )}
        </>
      )}
    </div>
  );
}
