"use client";

import { useRef, useState } from "react";
import { useClickOutside } from "@/hooks/useClickOutside";

export type RangeConfig = {
  key: string;
  label: string;
  min: number;
  max: number;
  initialMin?: number;
  initialMax?: number;
  format?: (value: number) => string;
};

function DualRangeSlider({
  min,
  max,
  valueMin,
  valueMax,
  format = (value) => String(value),
  onChange,
}: {
  min: number;
  max: number;
  valueMin: number;
  valueMax: number;
  format?: (value: number) => string;
  onChange: (min: number, max: number) => void;
}) {
  const leftPct = ((valueMin - min) / (max - min)) * 100;
  const rightPct = ((valueMax - min) / (max - min)) * 100;

  const handleMin = (e: React.ChangeEvent<HTMLInputElement>) => {
    onChange(Math.min(Number(e.target.value), valueMax - 1), valueMax);
  };

  const handleMax = (e: React.ChangeEvent<HTMLInputElement>) => {
    onChange(valueMin, Math.max(Number(e.target.value), valueMin + 1));
  };

  return (
    <div>
      <div className="relative flex h-5 items-center">
        <div className="absolute h-1 w-full rounded-full bg-[#E4E7EC]" />
        <div
          className="absolute h-1 rounded-full bg-[#1657D9]"
          style={{ left: `${leftPct}%`, width: `${rightPct - leftPct}%` }}
        />
        <input type="range" min={min} max={max} value={valueMin} onChange={handleMin} className="dual-range-input" />
        <input type="range" min={min} max={max} value={valueMax} onChange={handleMax} className="dual-range-input" />
      </div>

      <div className="mt-2 flex justify-between text-[13px] text-[#667085]">
        <span>
          From <strong className="font-semibold text-[#101828]">{format(valueMin)}</strong>
        </span>
        <span>
          To <strong className="font-semibold text-[#101828]">{format(valueMax)}</strong>
        </span>
      </div>
    </div>
  );
}

export default function FiltersDropdown({
  open,
  onClose,
  statusOptions,
  ranges,
  initialStatus,
  onApply,
  onClear,
}: {
  open: boolean;
  onClose: () => void;
  statusOptions: readonly string[];
  ranges: RangeConfig[];
  initialStatus?: Set<string>;
  onApply?: (status: Set<string>, values: Record<string, { min: number; max: number }>) => void;
  onClear?: () => void;
}) {
  const ref = useRef<HTMLDivElement | null>(null);
  const [status, setStatus] = useState<Set<string>>(initialStatus || new Set([statusOptions[0]]));
  const [values, setValues] = useState<Record<string, { min: number; max: number }>>(() =>
    Object.fromEntries(
      ranges.map((range) => [range.key, { min: range.initialMin ?? range.min, max: range.initialMax ?? range.max }])
    )
  );

  useClickOutside(ref, onClose, open);

  const toggleStatus = (option: string) => {
    setStatus(new Set([option]));
  };

  const handleClear = () => {
    setStatus(new Set([statusOptions[0]]));
    setValues(
      Object.fromEntries(
        ranges.map((range) => [range.key, { min: range.initialMin ?? range.min, max: range.initialMax ?? range.max }])
      )
    );
  };

  if (!open) return null;

  return (
    <div
      ref={ref}
      className="absolute right-0 top-[calc(100%+8px)] z-50 w-[450px] rounded-2xl border border-[#E4E7EC] bg-white shadow-[0_18px_40px_rgba(15,23,42,0.16)]"
    >
      <div className="border-b border-[#E4E7EC] px-5 py-4">
        <h2 className="text-[16px] font-semibold text-[#101828]">Filters</h2>
      </div>

      <div className="flex max-h-[70vh] flex-col gap-5 overflow-y-auto px-5 py-5">
        <div>
          <p className="mb-3 text-[13px] font-medium text-[#475467]">Status</p>
          <div className="flex flex-wrap gap-4">
            {statusOptions.map((option) => (
              <label key={option} className="flex cursor-pointer select-none items-center gap-2 text-[14px] font-medium text-[#101828]">
                <input
                  type="radio"
                  name="statusFilter"
                  checked={status.has(option)}
                  onChange={() => toggleStatus(option)}
                  className="h-4 w-4 cursor-pointer accent-[#1657D9]"
                />
                {option}
              </label>
            ))}
          </div>
        </div>

        {ranges.map((range) => (
          <div key={range.key}>
            <p className="mb-3 text-[13px] font-medium text-[#475467]">{range.label}</p>
            <DualRangeSlider
              min={range.min}
              max={range.max}
              valueMin={values[range.key].min}
              valueMax={values[range.key].max}
              format={range.format}
              onChange={(mn, mx) => setValues((prev) => ({ ...prev, [range.key]: { min: mn, max: mx } }))}
            />
          </div>
        ))}

        <hr className="border-[#E4E7EC]" />

        <div className="flex items-center justify-between gap-3">
          <button
            type="button"
            onClick={() => {
              handleClear();
              onClear?.();
            }}
            className="text-[13px] text-[#667085] transition-colors hover:text-[#101828] cursor-pointer"
          >
            Clear all
          </button>
          <button
            type="button"
            onClick={() => {
              onApply?.(status, values);
              onClose();
            }}
            className="rounded-lg bg-[#1657D9] px-5 py-2.5 text-[13px] font-medium text-white transition-colors hover:bg-[#1445B0] cursor-pointer"
          >
            Apply Filters
          </button>
        </div>
      </div>
    </div>
  );
}
