"use client";

import * as React from "react";
import { Check, Loader2 } from "lucide-react";

import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";

export type GlassMultiSelectItem = {
  id: string;
  label: string;
};

type GlassMultiSelectCardProps = {
  title: string;
  icon?: React.ReactNode;
  search: string;
  onSearchChange: (value: string) => void;
  items: readonly GlassMultiSelectItem[];
  selectedIds: readonly string[];
  onToggle: (id: string, checked: boolean) => void;
  onSelectAll: () => void;
  onSelectNone?: () => void;
  showSelectNone?: boolean;
  searchPlaceholder?: string;
  emptyLabel?: string;
  loading?: boolean;
  listClassName?: string;
  className?: string;
  /** When false, omit the selected count under the title. */
  showCount?: boolean;
  /** Denser chrome for tight layouts (e.g. pivot filters). */
  density?: "default" | "compact";
};

/**
 * Glass / liquid multi-select card — same visual language as Portfolio Scope.
 */
export function GlassMultiSelectCard({
  title,
  icon,
  search,
  onSearchChange,
  items,
  selectedIds,
  onToggle,
  onSelectAll,
  onSelectNone,
  showSelectNone = true,
  searchPlaceholder,
  emptyLabel = "No matches",
  loading = false,
  listClassName,
  className,
  showCount = true,
  density = "default",
}: GlassMultiSelectCardProps) {
  const compact = density === "compact";
  const selectedSet = React.useMemo(() => new Set(selectedIds), [selectedIds]);

  const visibleItems = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return [...items];
    return items.filter((item) => item.label.toLowerCase().includes(q));
  }, [items, search]);

  const orderedItems = React.useMemo(() => {
    const selected: GlassMultiSelectItem[] = [];
    const rest: GlassMultiSelectItem[] = [];
    for (const item of visibleItems) {
      if (selectedSet.has(item.id)) selected.push(item);
      else rest.push(item);
    }
    return [...selected, ...rest];
  }, [visibleItems, selectedSet]);

  return (
    <section
      className={cn(
        "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden border border-border/60 bg-card shadow-sm",
        compact ? "rounded-xl" : "rounded-2xl",
        className,
      )}
    >
      <div
        className={cn(
          "bg-gradient-to-r from-primary/10 via-transparent to-transparent",
          compact ? "px-3 py-1.5" : "px-4 py-3",
        )}
      >
        <div className="flex items-center justify-between gap-2">
          <div className={cn("flex min-w-0 items-center", compact ? "gap-2" : "gap-2.5")}>
            {icon ? (
              <span
                className={cn(
                  "flex shrink-0 items-center justify-center rounded-xl bg-primary text-primary-foreground shadow-md shadow-primary/25",
                  compact ? "size-6 rounded-lg" : "size-8",
                )}
              >
                {icon}
              </span>
            ) : null}
            <div className="min-w-0">
              <h3
                className={cn(
                  "font-semibold tracking-tight",
                  compact ? "text-xs" : "text-sm",
                )}
              >
                {title}
              </h3>
              {showCount ? (
                <p className="text-muted-foreground text-[11px] tabular-nums">
                  {selectedIds.length} of {items.length} selected
                </p>
              ) : null}
            </div>
          </div>
          <div className="flex shrink-0 items-center gap-2 text-xs">
            <button
              type="button"
              className="font-medium text-muted-foreground transition-colors hover:text-foreground disabled:opacity-40"
              disabled={loading || items.length === 0}
              onClick={onSelectAll}
            >
              All
            </button>
            {showSelectNone && onSelectNone ? (
              <>
                <span className="text-muted-foreground/40">·</span>
                <button
                  type="button"
                  className="font-medium text-muted-foreground transition-colors hover:text-foreground disabled:opacity-40"
                  disabled={loading || selectedIds.length === 0}
                  onClick={onSelectNone}
                >
                  None
                </button>
              </>
            ) : null}
          </div>
        </div>
      </div>

      <div
        className={cn(
          "border-t border-border/40 bg-white dark:bg-card",
          compact ? "space-y-1.5 px-2 py-2" : "space-y-2 px-3 py-3",
        )}
      >
        <Input
          placeholder={searchPlaceholder ?? `Search ${title.toLowerCase()}…`}
          value={search}
          onChange={(event) => onSearchChange(event.target.value)}
          className={cn(
            "border-border/60 bg-white dark:bg-background",
            compact ? "h-7 text-xs" : "h-9",
          )}
          aria-label={`Search ${title}`}
        />

        <div
          className={cn(
            "relative min-h-0 overflow-hidden border border-border/25 bg-white dark:bg-background",
            compact ? "rounded-lg p-0.5" : "rounded-xl p-1",
          )}
        >
          {loading ? (
            <div className="absolute inset-0 z-10 flex items-center justify-center bg-background/70 backdrop-blur-sm">
              <Loader2 className="size-4 animate-spin text-muted-foreground" />
            </div>
          ) : null}
          <div
            className={cn(
              "overflow-y-auto",
              listClassName ?? (compact ? "max-h-24" : "max-h-52 min-h-40"),
            )}
          >
            {orderedItems.length === 0 ? (
              <p
                className={cn(
                  "text-center text-muted-foreground text-xs",
                  compact ? "px-2 py-3" : "px-2 py-6",
                )}
              >
                {emptyLabel}
              </p>
            ) : (
              <ul className={cn(compact ? "space-y-0" : "space-y-0.5")}>
                {orderedItems.map((item) => {
                  const checked = selectedSet.has(item.id);
                  return (
                    <li key={item.id}>
                      <label
                        className={cn(
                          "flex cursor-pointer items-center border border-border/20 bg-white text-sm transition-colors dark:bg-background",
                          "hover:border-border/40 hover:bg-white dark:hover:bg-background",
                          checked && "border-border/40",
                          compact
                            ? "gap-2 rounded-md px-2 py-1 text-xs"
                            : "gap-2.5 rounded-lg px-2.5 py-2",
                        )}
                      >
                        <Checkbox
                          checked={checked}
                          onCheckedChange={(value) => onToggle(item.id, value === true)}
                          className={compact ? "size-3.5" : undefined}
                        />
                        <span className="min-w-0 flex-1 truncate font-medium leading-tight text-foreground">
                          {item.label.trim() || item.id}
                        </span>
                        {checked ? (
                          <Check
                            className={cn(
                              "shrink-0 text-primary",
                              compact ? "size-3" : "size-3.5",
                            )}
                          />
                        ) : null}
                      </label>
                    </li>
                  );
                })}
              </ul>
            )}
          </div>
        </div>
      </div>
    </section>
  );
}
