"use client";

import { useEffect, useId, useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { IoFilterOutline } from "react-icons/io5";
import { useClickOutside } from "@/hooks/useClickOutside";
import { IconButton } from "@/components/IconButton";

export type FilterGroup = {
  label: string;
  param: string;
  options: { value: string; label: string }[];
};

type Props = {
  groups: FilterGroup[];
  values: Record<string, string[]>;
  onChange: (param: string, selected: string[]) => void;
  menuClassName?: string;
};

export function FilterDropdown({ groups, values, onChange, menuClassName }: Props) {
  const [open, setOpen] = useState(false);
  const buttonRef = useRef<HTMLButtonElement>(null);
  const menuRef = useRef<HTMLDivElement>(null);
  const menuId = useId();

  const activeCount = Object.values(values).reduce((sum, arr) => sum + arr.length, 0);

  useClickOutside([buttonRef, menuRef], () => setOpen(false), open);

  useEffect(() => {
    if (!open) return;

    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape") setOpen(false);
    };

    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [open]);

  const toggle = (param: string, value: string) => {
    const current = values[param] ?? [];
    const next = current.includes(value) ? current.filter((v) => v !== value) : [...current, value];
    onChange(param, next);
  };

  return (
    <div className="relative">
      <IconButton
        ref={buttonRef}
        onClick={() => setOpen((v) => !v)}
        className="text-lg"
        aria-haspopup="true"
        aria-expanded={open}
        aria-controls={menuId}
        aria-label="Filter releases"
      >
        <span className="relative">
          <IoFilterOutline />
          {activeCount > 0 ? (
            <span className="absolute -top-1.5 -right-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-trptkblue text-xs leading-none font-bold text-white dark:bg-white dark:text-lighttext">
              {activeCount}
            </span>
          ) : null}
        </span>
      </IconButton>

      <AnimatePresence>
        {open ? (
          <motion.div
            ref={menuRef}
            id={menuId}
            initial={{ opacity: 0, y: -8 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -8 }}
            transition={{ type: "tween", ease: "easeInOut", duration: 0.25 }}
            className={
              menuClassName ??
              "absolute right-0 z-20 mt-4 min-w-52 overflow-hidden rounded-2xl bg-lightbg p-4 shadow-lg ring-1 ring-lightline transition-[box-shadow,color,background-color] duration-300 ease-in-out hover:ring-lightline-hover dark:bg-darkbg dark:ring-darkline dark:hover:ring-darkline-hover"
            }
          >
            {groups.map((group, gi) => (
              <div key={group.param}>
                {gi > 0 ? <div className="mt-4 border-t border-lightline-mid pt-4 dark:border-darkline-mid" /> : null}

                <p className="mb-1 text-lightsec dark:text-darksec">{group.label}</p>

                <div className="flex flex-col gap-2">
                  {group.options.map((opt) => {
                    const checked = (values[group.param] ?? []).includes(opt.value);

                    return (
                      <button
                        key={opt.value}
                        type="button"
                        role="checkbox"
                        aria-checked={checked}
                        onClick={() => toggle(group.param, opt.value)}
                        className={[
                          "flex w-full items-center gap-3 text-left text-sm",
                          "transition-colors duration-200 ease-in-out",
                          checked ? "font-medium text-current" : "text-lightsec dark:text-darksec",
                          "hover:text-trptkblue dark:hover:text-white",
                        ].join(" ")}
                      >
                        <span
                          className={[
                            "flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors duration-200",
                            checked
                              ? "border-trptkblue bg-trptkblue text-darktext dark:border-white dark:bg-white dark:text-lighttext"
                              : "border-lightline-strong dark:border-darkline-strong",
                          ].join(" ")}
                        >
                          {checked ? (
                            <svg
                              viewBox="0 0 12 12"
                              className="h-2.5 w-2.5"
                              fill="none"
                              stroke="currentColor"
                              strokeWidth={2}
                              strokeLinecap="round"
                              strokeLinejoin="round"
                            >
                              <path d="M2 6l3 3 5-5" />
                            </svg>
                          ) : null}
                        </span>
                        <span>{opt.label}</span>
                      </button>
                    );
                  })}
                </div>
              </div>
            ))}
          </motion.div>
        ) : null}
      </AnimatePresence>
    </div>
  );
}
