"use client";

import * as React from "react";
import { Search, X } from "lucide-react";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { adminUsersTexts } from "@/lib/i18n/admin-users";
import { cn } from "@/lib/utils";

export type MultiOption = {
  value: string;
  label: string;
  /** Faded second line (category, key, …). */
  hint?: string;
  muted?: boolean;
};

const MAX_VISIBLE = 300;

/**
 * Checkbox list that submits a single comma-separated hidden field.
 * Used for "allowed payment methods" and "hidden services".
 */
export function CheckboxMultiSelect({
  name,
  label,
  hint,
  options,
  defaultValue,
  searchable,
  searchPlaceholder,
  emptyText,
  heightClass = "max-h-56",
}: {
  name: string;
  label: string;
  hint?: string;
  options: MultiOption[];
  defaultValue: string[];
  searchable?: boolean;
  searchPlaceholder?: string;
  emptyText?: string;
  heightClass?: string;
}) {
  const [selected, setSelected] = React.useState<string[]>(defaultValue);
  const [term, setTerm] = React.useState("");

  const filtered = React.useMemo(() => {
    const q = term.trim().toLowerCase();
    if (!q) return options;
    return options.filter(
      (o) =>
        o.label.toLowerCase().includes(q) ||
        o.value.toLowerCase().includes(q) ||
        (o.hint ?? "").toLowerCase().includes(q),
    );
  }, [options, term]);

  const visible = filtered.slice(0, MAX_VISIBLE);
  const hiddenCount = filtered.length - visible.length;

  function toggle(value: string, checked: boolean) {
    setSelected((prev) =>
      checked ? [...new Set([...prev, value])] : prev.filter((v) => v !== value),
    );
  }

  return (
    <div className="space-y-1.5">
      <input type="hidden" name={name} value={selected.join(",")} />

      <div className="flex items-center justify-between gap-2">
        <Label className="text-xs font-medium">{label}</Label>
        {selected.length ? (
          <button
            type="button"
            onClick={() => setSelected([])}
            className="inline-flex items-center gap-1 text-[11px] text-muted-foreground transition-colors hover:text-foreground"
          >
            <X className="size-3" />
            {adminUsersTexts.edit.selected.replace("{n}", String(selected.length))} ·{" "}
            {adminUsersTexts.edit.clearSelection}
          </button>
        ) : null}
      </div>

      {searchable ? (
        <div className="relative">
          <Search className="pointer-events-none absolute top-1/2 left-2 size-3.5 -translate-y-1/2 text-muted-foreground" />
          <Input
            value={term}
            onChange={(e) => setTerm(e.target.value)}
            placeholder={searchPlaceholder}
            className="h-7 pl-7 text-sm"
          />
        </div>
      ) : null}

      <div className={cn("overflow-y-auto rounded-lg border", heightClass)}>
        {visible.length === 0 ? (
          <p className="px-2.5 py-4 text-center text-xs text-muted-foreground">
            {emptyText ?? adminUsersTexts.rates.empty}
          </p>
        ) : (
          <ul className="divide-y">
            {visible.map((option) => {
              const checked = selected.includes(option.value);
              const id = `${name}-${option.value}`;
              return (
                <li key={option.value}>
                  <label
                    htmlFor={id}
                    className={cn(
                      "flex cursor-pointer items-center gap-2 px-2.5 py-1.5 transition-colors hover:bg-muted/50",
                      checked && "bg-blue-600/5 dark:bg-blue-500/10",
                    )}
                  >
                    <Checkbox
                      id={id}
                      checked={checked}
                      onCheckedChange={(value) => toggle(option.value, value === true)}
                    />
                    <span className="min-w-0 flex-1 leading-tight">
                      <span
                        className={cn(
                          "block truncate text-sm",
                          option.muted && "text-muted-foreground",
                        )}
                      >
                        {option.label}
                      </span>
                      {option.hint ? (
                        <span className="block truncate text-[11px] text-muted-foreground">
                          {option.hint}
                        </span>
                      ) : null}
                    </span>
                  </label>
                </li>
              );
            })}
          </ul>
        )}
        {hiddenCount > 0 ? (
          <p className="border-t px-2.5 py-1.5 text-[11px] text-muted-foreground">
            +{hiddenCount} more — narrow the filter to see them.
          </p>
        ) : null}
      </div>

      {hint ? <p className="text-[11px] text-muted-foreground">{hint}</p> : null}
    </div>
  );
}

export default CheckboxMultiSelect;
