"use client";

import { Fragment } from "react";
import { Check, ChevronDown, Layers, Minus } from "lucide-react";
import {
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/app/shadcn_components/ui/dropdown-menu";
import { Card } from "@/app/shadcn_components/ui/card";

export type GroupLeaf = {
  value: string;
  // Full label, used in the trigger when this leaf is selected outside the
  // context of a fully-checked parent.
  label: string;
  // Short label rendered under a parent header (the parent already provides
  // context). Falls back to `label`.
  shortLabel?: string;
  muted?: boolean;
};

export type GroupNode =
  | { kind: "leaf"; leaf: GroupLeaf }
  | {
      kind: "parent";
      label: string;
      muted?: boolean;
      children: GroupLeaf[];
    };

interface GroupFilterProps {
  options: GroupNode[];
  selected: string[];
  onChange: (next: string[]) => void;
  variant?: "card" | "inline";
}

function GroupDropdown({
  options,
  selected,
  onChange,
  triggerClassName,
  align = "start",
}: GroupFilterProps & {
  triggerClassName: string;
  align?: "start" | "end";
}) {
  const selectedSet = new Set(selected);

  const toggleLeaf = (value: string, checked: boolean) => {
    if (checked) {
      onChange([...selected, value]);
    } else {
      onChange(selected.filter((v) => v !== value));
    }
  };

  const toggleParent = (childValues: string[]) => {
    const allChecked = childValues.every((v) => selectedSet.has(v));
    if (allChecked) {
      const remove = new Set(childValues);
      onChange(selected.filter((v) => !remove.has(v)));
    } else {
      const merged = new Set(selected);
      for (const v of childValues) merged.add(v);
      onChange(Array.from(merged));
    }
  };

  // Trigger chunks: fully-selected parents collapse to the parent's label;
  // standalone leaves and partial-parent children contribute their own labels.
  const triggerChunks: string[] = [];
  for (const node of options) {
    if (node.kind === "leaf") {
      if (selectedSet.has(node.leaf.value)) triggerChunks.push(node.leaf.label);
    } else {
      const childValues = node.children.map((c) => c.value);
      const allSelected =
        childValues.length > 0 && childValues.every((v) => selectedSet.has(v));
      if (allSelected) {
        triggerChunks.push(node.label);
      } else {
        for (const child of node.children) {
          if (selectedSet.has(child.value)) triggerChunks.push(child.label);
        }
      }
    }
  }

  const triggerLabel =
    triggerChunks.length === 0
      ? "All groups"
      : triggerChunks.length === 1
        ? triggerChunks[0]
        : `${triggerChunks[0]} +${triggerChunks.length - 1}`;

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <button type="button" className={triggerClassName}>
          <span className="flex items-center gap-2 min-w-0">
            <Layers className="h-3.5 w-3.5 shrink-0 text-brandblue" />
            <span className="truncate">{triggerLabel}</span>
          </span>
          <ChevronDown className="h-3.5 w-3.5 shrink-0 text-gray-400" />
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent
        align={align}
        className="min-w-[240px] max-w-[360px] w-[--radix-dropdown-menu-trigger-width]"
      >
        <DropdownMenuLabel className="text-xs text-gray-500 flex items-center justify-between">
          <span>Groups</span>
          {selected.length > 0 && (
            <button
              type="button"
              onClick={() => onChange([])}
              className="text-[11px] text-brandblue hover:underline font-medium"
            >
              Clear
            </button>
          )}
        </DropdownMenuLabel>
        <DropdownMenuSeparator />
        <div className="max-h-72 overflow-y-auto">
          {options.map((node, i) => {
            const needsSeparator = i > 0;
            if (node.kind === "leaf") {
              return (
                <Fragment key={`leaf-${node.leaf.value}`}>
                  {needsSeparator && <DropdownMenuSeparator />}
                  <DropdownMenuCheckboxItem
                    checked={selectedSet.has(node.leaf.value)}
                    onCheckedChange={(v) => toggleLeaf(node.leaf.value, !!v)}
                    onSelect={(e) => e.preventDefault()}
                    className="text-sm"
                  >
                    {node.leaf.muted ? (
                      <span className="italic text-gray-500">
                        {node.leaf.label}
                      </span>
                    ) : (
                      node.leaf.label
                    )}
                  </DropdownMenuCheckboxItem>
                </Fragment>
              );
            }

            const childValues = node.children.map((c) => c.value);
            const selectedCount = childValues.filter((v) =>
              selectedSet.has(v),
            ).length;
            const parentState: boolean | "indeterminate" =
              selectedCount === 0
                ? false
                : selectedCount === childValues.length
                  ? true
                  : "indeterminate";

            return (
              <Fragment key={`parent-${node.label}`}>
                {needsSeparator && <DropdownMenuSeparator />}
                <DropdownMenuItem
                  onSelect={(e) => {
                    e.preventDefault();
                    toggleParent(childValues);
                  }}
                  className="relative flex items-center py-1.5 pl-8 pr-2 text-sm font-semibold"
                >
                  <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
                    {parentState === true ? (
                      <Check className="h-4 w-4" />
                    ) : parentState === "indeterminate" ? (
                      <Minus className="h-4 w-4" />
                    ) : null}
                  </span>
                  {node.muted ? (
                    <span className="italic text-gray-500">{node.label}</span>
                  ) : (
                    node.label
                  )}
                </DropdownMenuItem>
                {node.children.map((child) => (
                  <DropdownMenuCheckboxItem
                    key={child.value}
                    checked={selectedSet.has(child.value)}
                    onCheckedChange={(v) => toggleLeaf(child.value, !!v)}
                    onSelect={(e) => e.preventDefault()}
                    className="text-sm pl-12"
                  >
                    {child.muted ? (
                      <span className="italic text-gray-500">
                        {child.shortLabel ?? child.label}
                      </span>
                    ) : (
                      (child.shortLabel ?? child.label)
                    )}
                  </DropdownMenuCheckboxItem>
                ))}
              </Fragment>
            );
          })}
        </div>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

export default function GroupFilter(props: GroupFilterProps) {
  const { variant = "card" } = props;

  if (variant === "inline") {
    return (
      <GroupDropdown
        {...props}
        triggerClassName="h-9 px-3 pr-2 border border-brandblue/20 rounded-lg bg-white text-gray-800 font-medium text-sm focus:ring-2 focus:ring-brandblue focus:border-brandblue focus:outline-none transition-all flex items-center gap-2 min-w-[160px] max-w-[280px]"
      />
    );
  }

  return (
    <Card className="flex flex-col justify-center items-center border border-brandblue/10 bg-gradient-to-br from-brandlightblue/20 to-white shadow-sm hover:shadow-md transition-shadow p-5">
      <div className="w-full flex flex-col">
        <p className="text-xs uppercase tracking-wide text-gray-600 mb-3 font-semibold">
          Filter by Group
        </p>
        <GroupDropdown
          {...props}
          triggerClassName="w-full px-4 py-2.5 pr-3 border border-brandblue/20 rounded-lg bg-white text-gray-800 font-medium text-sm focus:ring-2 focus:ring-brandblue focus:border-brandblue focus:outline-none transition-all flex items-center justify-between gap-2"
        />
      </div>
    </Card>
  );
}
