import { useEffect, useMemo, useRef, useState, type CSSProperties } from "react";
import type { ComponentRecord } from "../types";
import { Grid3X3, LayoutGrid, Search, X, ZoomIn } from "lucide-react";
import ComponentPreviewMini, { getComponentDescription } from "./ComponentPreviewMini";
import { getBlockComponent } from "@/components/page-blocks";
import { resolvePreviewContent } from "@/lib/contentPlaceholders";
import { SiteChromeFrame } from "@/components/SiteChromeFrame";
import { ComponentPreviewBySlug } from "../pages/ComponentPreviews";
import { filterComponentsBySearch } from "../lib/componentSearch";
import { getActiveComparisonGroups, getComponentGuideDescription, getComponentCatalog } from "../lib/componentCatalog";
import ComponentGuideInfo, { ComponentDisplayTitle } from "./ComponentGuideInfo";
import SimilarComponentsCompare from "./SimilarComponentsCompare";

export type ComponentPickerTarget = {
  sectionIndex?: number;
  slotIndex?: number;
};

type ViewMode = "grid" | "card";

type ComponentPickerModalProps = {
  components: ComponentRecord[];
  target: ComponentPickerTarget | null;
  onSelect: (component: ComponentRecord, target: ComponentPickerTarget | null) => void;
  onClose: () => void;
};

function categoryBadgeStyle(category: string): CSSProperties {
  const map: Record<string, { bg: string; color: string }> = {
    Landing: { bg: "#dbeafe", color: "#1d4ed8" },
    Grade: { bg: "#dcfce7", color: "#15803d" },
    Curriculum: { bg: "#fef3c7", color: "#b45309" },
    Course: { bg: "#ede9fe", color: "#6d28d9" },
    Quarter: { bg: "#fce7f3", color: "#be185d" },
  };
  const colors = map[category] ?? { bg: "#f1f5f9", color: "#475569" };
  return {
    display: "inline-block",
    padding: "2px 8px",
    borderRadius: 999,
    fontSize: 11,
    fontWeight: 600,
    background: colors.bg,
    color: colors.color,
  };
}

function ComponentDetailPreview({ component }: { component: ComponentRecord }) {
  const BlockComp = getBlockComponent(component.slug);
  const content = resolvePreviewContent((component.content ?? {}) as Record<string, unknown>, {
    blockSlug: component.slug,
  });

  const inner = BlockComp ? (
    <BlockComp content={content} />
  ) : (
    <ComponentPreviewBySlug slug={component.slug} content={content} />
  );

  return (
    <SiteChromeFrame
      previewMode
      showGlobalFooter={component.slug !== "footer"}
      className="rounded-xl overflow-hidden border border-slate-200"
    >
      <div className="p-4">{inner}</div>
    </SiteChromeFrame>
  );
}

export default function ComponentPickerModal({
  components,
  target,
  onSelect,
  onClose,
}: ComponentPickerModalProps) {
  const [search, setSearch] = useState("");
  const [categoryFilter, setCategoryFilter] = useState("");
  const [viewMode, setViewMode] = useState<ViewMode>("card");
  const [detailComponent, setDetailComponent] = useState<ComponentRecord | null>(null);
  const searchInputRef = useRef<HTMLInputElement>(null);

  const categories = useMemo(() => {
    const set = new Set<string>();
    components.forEach((c) => {
      if (c.category) set.add(c.category);
    });
    return Array.from(set).sort();
  }, [components]);

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

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

  const targetLabel = (() => {
    if (target?.sectionIndex === undefined) return "Add to page";
    if (target.slotIndex !== undefined) {
      return `Add to section ${target.sectionIndex + 1}, slot ${target.slotIndex + 1}`;
    }
    return `Add to section ${target.sectionIndex + 1}`;
  })();

  const confirmSelect = (component: ComponentRecord) => {
    onSelect(component, target);
    onClose();
  };

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") {
        event.preventDefault();
        event.stopPropagation();
      }
    };
    window.addEventListener("keydown", handleKeyDown, true);
    return () => window.removeEventListener("keydown", handleKeyDown, true);
  }, []);

  useEffect(() => {
    const timer = window.setTimeout(() => searchInputRef.current?.focus(), 0);
    return () => window.clearTimeout(timer);
  }, []);

  return (
    <>
      <div
        style={{
          position: "fixed",
          inset: 0,
          zIndex: 60,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          background: "rgba(15, 23, 42, 0.45)",
          padding: 20,
        }}
      >
        <div
          role="dialog"
          aria-modal="true"
          aria-labelledby="component-picker-title"
          style={{
            background: "#fff",
            borderRadius: 20,
            boxShadow: "0 24px 48px rgba(0,0,0,0.18)",
            width: "100%",
            maxWidth: 960,
            maxHeight: "92vh",
            display: "flex",
            flexDirection: "column",
            overflow: "hidden",
          }}
        >
          <div
            style={{
              display: "flex",
              alignItems: "flex-start",
              justifyContent: "space-between",
              gap: 16,
              padding: "20px 24px",
              borderBottom: "1px solid #e5e7eb",
            }}
          >
            <div>
              <h2 id="component-picker-title" style={{ margin: 0, fontSize: 20, fontWeight: 700, color: "#0f172a" }}>
                Choose a component
              </h2>
              <p style={{ margin: "6px 0 0", fontSize: 14, color: "#64748b" }}>
                {targetLabel} — preview layouts before adding them to your page.
              </p>
            </div>
            <button
              type="button"
              onClick={onClose}
              aria-label="Close"
              style={{ padding: 8, border: "none", background: "none", cursor: "pointer", color: "#64748b", flexShrink: 0 }}
            >
              <X size={22} />
            </button>
          </div>

          <div
            style={{
              padding: "16px 24px",
              borderBottom: "1px solid #f1f5f9",
              background: "#fafbfc",
            }}
          >
            <label htmlFor="component-picker-search" style={{ display: "block", fontSize: 13, fontWeight: 600, color: "#374151", marginBottom: 8 }}>
              Search components
            </label>
            <div style={{ position: "relative" }}>
              <Search size={18} style={{ position: "absolute", left: 14, top: "50%", transform: "translateY(-50%)", color: "#94a3b8", pointerEvents: "none" }} />
              <input
                ref={searchInputRef}
                id="component-picker-search"
                type="search"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="Search by component name (e.g. hero, skill)..."
                aria-label="Search components by name"
                autoComplete="off"
                style={{
                  width: "100%",
                  padding: hasActiveSearch ? "11px 40px 11px 42px" : "11px 14px 11px 42px",
                  border: "1px solid #cbd5e1",
                  borderRadius: 12,
                  fontSize: 15,
                  boxSizing: "border-box",
                  background: "#fff",
                  outline: "none",
                }}
              />
              {hasActiveSearch && (
                <button
                  type="button"
                  onClick={() => {
                    setSearch("");
                    searchInputRef.current?.focus();
                  }}
                  aria-label="Clear search"
                  style={{
                    position: "absolute",
                    right: 10,
                    top: "50%",
                    transform: "translateY(-50%)",
                    padding: 4,
                    border: "none",
                    background: "transparent",
                    cursor: "pointer",
                    color: "#94a3b8",
                    display: "flex",
                    alignItems: "center",
                  }}
                >
                  <X size={18} />
                </button>
              )}
            </div>
            <p
              aria-live="polite"
              style={{ margin: "8px 0 0", fontSize: 13, color: "#64748b" }}
            >
              {hasActiveSearch || categoryFilter
                ? `${filtered.length} of ${components.length} component${components.length === 1 ? "" : "s"} shown`
                : `${components.length} component${components.length === 1 ? "" : "s"} available`}
            </p>
          </div>

          <div
            style={{
              display: "flex",
              flexWrap: "wrap",
              gap: 10,
              alignItems: "center",
              padding: "12px 24px",
              borderBottom: "1px solid #f1f5f9",
              background: "#fff",
            }}
          >
            <select
              value={categoryFilter}
              onChange={(e) => setCategoryFilter(e.target.value)}
              style={{ padding: "9px 12px", border: "1px solid #e2e8f0", borderRadius: 10, fontSize: 14, minWidth: 140 }}
            >
              <option value="">All categories</option>
              {categories.map((cat) => (
                <option key={cat} value={cat}>
                  {cat}
                </option>
              ))}
            </select>
            <div style={{ display: "inline-flex", border: "1px solid #e2e8f0", borderRadius: 10, overflow: "hidden", marginLeft: "auto" }}>
              <button
                type="button"
                onClick={() => setViewMode("card")}
                title="Card view"
                style={{
                  display: "inline-flex",
                  alignItems: "center",
                  gap: 6,
                  padding: "8px 12px",
                  border: "none",
                  background: viewMode === "card" ? "#0f172a" : "#fff",
                  color: viewMode === "card" ? "#fff" : "#475569",
                  cursor: "pointer",
                  fontSize: 13,
                  fontWeight: 500,
                }}
              >
                <LayoutGrid size={16} /> Cards
              </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>
          </div>

          <div style={{ flex: 1, overflow: "auto", padding: 24 }}>
            {comparisonGroups.includes("whole-child-portrait") && (
              <SimilarComponentsCompare
                components={filtered}
                onSelect={(component) => setDetailComponent(component)}
              />
            )}
            {filtered.length === 0 ? (
              <div style={{ textAlign: "center", padding: 48, 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 }}>
                  {hasActiveSearch || categoryFilter
                    ? "Try a different search term or clear your filters."
                    : "No components are available in the library."}
                </p>
                {(hasActiveSearch || categoryFilter) && (
                  <button
                    type="button"
                    onClick={() => {
                      setSearch("");
                      setCategoryFilter("");
                      searchInputRef.current?.focus();
                    }}
                    style={{
                      marginTop: 16,
                      padding: "9px 16px",
                      background: "#f1f5f9",
                      border: "none",
                      borderRadius: 10,
                      cursor: "pointer",
                      fontWeight: 500,
                      fontSize: 14,
                      color: "#334155",
                    }}
                  >
                    Clear search
                  </button>
                )}
              </div>
            ) : (
              <div
                style={{
                  display: "grid",
                  gridTemplateColumns: viewMode === "grid"
                    ? "repeat(auto-fill, minmax(160px, 1fr))"
                    : "repeat(auto-fill, minmax(260px, 1fr))",
                  gap: viewMode === "grid" ? 12 : 16,
                }}
              >
                {filtered.map((component) => {
                  const hasGuide = Boolean(getComponentGuideDescription(component));
                  const contentDescription = getComponentDescription(component);
                  const isGrid = viewMode === "grid";

                  return (
                    <button
                      key={component.id}
                      type="button"
                      onClick={() => setDetailComponent(component)}
                      style={{
                        display: "flex",
                        flexDirection: "column",
                        textAlign: "left",
                        padding: isGrid ? 10 : 14,
                        border: "1px solid #e2e8f0",
                        borderRadius: 14,
                        background: "#fff",
                        cursor: "pointer",
                        transition: "box-shadow 0.15s ease, border-color 0.15s ease",
                        boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
                        gap: isGrid ? 8 : 10,
                      }}
                      onMouseEnter={(e) => {
                        e.currentTarget.style.borderColor = "#94a3b8";
                        e.currentTarget.style.boxShadow = "0 4px 12px rgba(0,0,0,0.08)";
                      }}
                      onMouseLeave={(e) => {
                        e.currentTarget.style.borderColor = "#e2e8f0";
                        e.currentTarget.style.boxShadow = "0 1px 2px rgba(0,0,0,0.04)";
                      }}
                    >
                      <ComponentPreviewMini
                        component={component}
                        scale={isGrid ? 0.28 : 0.32}
                        maxHeight={isGrid ? 110 : 148}
                      />
                      <div style={{ minWidth: 0 }}>
                        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 8 }}>
                          <ComponentDisplayTitle
                            component={component}
                            style={{ fontWeight: 600, fontSize: isGrid ? 13 : 15, color: "#0f172a", lineHeight: 1.3 }}
                          />
                          <ZoomIn size={14} style={{ color: "#94a3b8", flexShrink: 0, marginTop: 2 }} />
                        </div>
                        {!isGrid && component.category && (
                          <span style={{ ...categoryBadgeStyle(component.category), marginTop: 6 }}>{component.category}</span>
                        )}
                        {!isGrid && !hasGuide && contentDescription && (
                          <p style={{ margin: "8px 0 0", fontSize: 12, color: "#64748b", lineHeight: 1.45, display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>
                            {contentDescription}
                          </p>
                        )}
                        {!isGrid && hasGuide && <ComponentGuideInfo component={component} variant="compact" />}
                        {isGrid && component.category && (
                          <span style={{ fontSize: 11, color: "#94a3b8", marginTop: 2, display: "block" }}>{component.category}</span>
                        )}
                      </div>
                    </button>
                  );
                })}
              </div>
            )}
          </div>

          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
              gap: 12,
              padding: "12px 24px",
              borderTop: "1px solid #e5e7eb",
              background: "#fafbfc",
            }}
          >
            <p style={{ margin: 0, fontSize: 13, color: "#64748b", flex: 1 }}>
              {hasActiveSearch
                ? `Showing ${filtered.length} result${filtered.length === 1 ? "" : "s"} for “${search.trim()}”`
                : `${filtered.length} component${filtered.length === 1 ? "" : "s"} · Click a card to preview larger, then confirm to add.`}
            </p>
            <button
              type="button"
              onClick={onClose}
              style={{ padding: "9px 18px", background: "#f1f5f9", border: "none", borderRadius: 10, cursor: "pointer", fontWeight: 500, fontSize: 14, flexShrink: 0 }}
            >
              Cancel
            </button>
          </div>
        </div>
      </div>

      {detailComponent && (
        <div
          style={{
            position: "fixed",
            inset: 0,
            zIndex: 70,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            background: "rgba(15, 23, 42, 0.55)",
            padding: 20,
          }}
        >
          <div
            role="dialog"
            aria-modal="true"
            aria-labelledby="component-detail-title"
            style={{
              background: "#fff",
              borderRadius: 20,
              boxShadow: "0 24px 48px rgba(0,0,0,0.2)",
              width: "100%",
              maxWidth: 720,
              maxHeight: "90vh",
              display: "flex",
              flexDirection: "column",
              overflow: "hidden",
            }}
          >
            <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16, padding: "18px 22px", borderBottom: "1px solid #e5e7eb" }}>
              <div>
                <ComponentDisplayTitle
                  id="component-detail-title"
                  component={detailComponent}
                  as="h3"
                  style={{ margin: 0, fontSize: 18, fontWeight: 700, color: "#0f172a" }}
                />
                <div style={{ display: "flex", flexWrap: "wrap", alignItems: "center", gap: 8, marginTop: 6 }}>
                  {detailComponent.category && <span style={categoryBadgeStyle(detailComponent.category)}>{detailComponent.category}</span>}
                  <span style={{ fontSize: 12, color: "#94a3b8" }}>{detailComponent.slug}</span>
                </div>
              </div>
              <button
                type="button"
                onClick={() => setDetailComponent(null)}
                aria-label="Close preview"
                style={{ padding: 8, border: "none", background: "none", cursor: "pointer", color: "#64748b" }}
              >
                <X size={20} />
              </button>
            </div>
            <div style={{ flex: 1, overflow: "auto", padding: 20, background: "#f8fafc" }}>
              <ComponentGuideInfo component={detailComponent} variant="full" />
              {getComponentCatalog(detailComponent.slug)?.topicGroup && (
                <SimilarComponentsCompare components={components} onSelect={(component) => setDetailComponent(component)} />
              )}
              <div style={{ background: "#fff", borderRadius: 12, border: "1px solid #e2e8f0", padding: 16, overflow: "auto", maxHeight: "min(52vh, 480px)" }}>
                <ComponentDetailPreview component={detailComponent} />
              </div>
            </div>
            <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, padding: "14px 22px", borderTop: "1px solid #e5e7eb" }}>
              <button
                type="button"
                onClick={() => setDetailComponent(null)}
                style={{ padding: "10px 18px", background: "#f1f5f9", border: "none", borderRadius: 10, cursor: "pointer", fontWeight: 500, fontSize: 14 }}
              >
                Back
              </button>
              <button
                type="button"
                onClick={() => confirmSelect(detailComponent)}
                style={{ padding: "10px 20px", background: "#0f172a", color: "#fff", border: "none", borderRadius: 10, cursor: "pointer", fontWeight: 600, fontSize: 14 }}
              >
                Add component
              </button>
            </div>
          </div>
        </div>
      )}

      <style>{`
        @keyframes component-preview-shimmer {
          0% { background-position: 200% 0; }
          100% { background-position: -200% 0; }
        }
      `}</style>
    </>
  );
}
