"use client";

import { useState, useRef, useEffect, useCallback } from "react";
import type { ColumnDef } from "@capakraken/shared";

interface ColumnTogglePanelProps {
  allColumns: ColumnDef[];
  visibleKeys: string[];
  onSetVisible: (keys: string[]) => void;
  defaultKeys: string[];
}

export function ColumnTogglePanel({
  allColumns,
  visibleKeys,
  onSetVisible,
  defaultKeys,
}: ColumnTogglePanelProps) {
  const [open, setOpen] = useState(false);
  const panelRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    function handleClick(e: MouseEvent) {
      if (panelRef.current && !panelRef.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, [open]);

  const dragKey = useRef<string | null>(null);

  function toggle(key: string) {
    const col = allColumns.find((c) => c.key === key);
    if (!col?.hideable) return; // always-visible columns can't be toggled
    const next = visibleKeys.includes(key)
      ? visibleKeys.filter((k) => k !== key)
      : [...visibleKeys, key];
    onSetVisible(next);
  }

  function reset() {
    onSetVisible(defaultKeys);
  }

  const reorder = useCallback((fromKey: string, toKey: string) => {
    if (fromKey === toKey) return;
    const next = [...visibleKeys];
    const from = next.indexOf(fromKey);
    const to = next.indexOf(toKey);
    if (from === -1 || to === -1) return;
    next.splice(from, 1);
    next.splice(to, 0, fromKey);
    onSetVisible(next);
  }, [visibleKeys, onSetVisible]);

  const builtins = allColumns.filter((c) => !c.isCustom);
  const customs  = allColumns.filter((c) =>  c.isCustom);

  return (
    <div className="relative" ref={panelRef}>
      <button
        type="button"
        onClick={() => setOpen((o) => !o)}
        title="Toggle columns"
        className={`p-1.5 rounded-lg border text-sm transition-colors ${
          open
            ? "border-brand-400 bg-brand-50 text-brand-700"
            : "border-gray-300 text-gray-500 hover:border-gray-400 hover:text-gray-700"
        }`}
        aria-label="Column visibility"
      >
        {/* columns icon */}
        <svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden>
          <rect x="1" y="3" width="4" height="10" rx="1" stroke="currentColor" strokeWidth="1.5"/>
          <rect x="6" y="3" width="4" height="10" rx="1" stroke="currentColor" strokeWidth="1.5"/>
          <rect x="11" y="3" width="4" height="10" rx="1" stroke="currentColor" strokeWidth="1.5"/>
        </svg>
      </button>

      {open && (
        <div className="absolute right-0 top-full mt-1 z-50 w-52 bg-white border border-gray-200 rounded-xl shadow-xl py-2">
          <div className="px-3 pb-1 flex items-center justify-between">
            <span className="text-xs font-semibold text-gray-500 uppercase tracking-wide">Columns</span>
            <button
              type="button"
              onClick={reset}
              className="text-xs text-brand-600 hover:text-brand-800"
            >
              Reset
            </button>
          </div>

          <div className="max-h-72 overflow-y-auto">
            {builtins.map((col) => {
              const isVisible = visibleKeys.includes(col.key);
              return (
                <div
                  key={col.key}
                  draggable={col.hideable && isVisible}
                  onDragStart={() => { dragKey.current = col.key; }}
                  onDragOver={(e) => { e.preventDefault(); }}
                  onDrop={() => { if (dragKey.current) reorder(dragKey.current, col.key); dragKey.current = null; }}
                  className={`flex items-center gap-2 px-3 py-1.5 hover:bg-gray-50 ${
                    !col.hideable ? "opacity-50" : "cursor-grab"
                  }`}
                >
                  {col.hideable && isVisible && (
                    <span className="text-gray-300 text-xs select-none">⠿</span>
                  )}
                  <label className="flex items-center gap-2 flex-1 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={isVisible}
                      onChange={() => toggle(col.key)}
                      disabled={!col.hideable}
                      className="rounded border-gray-300 text-brand-600 focus:ring-brand-500"
                    />
                    <span className="text-sm text-gray-700">{col.label}</span>
                  </label>
                </div>
              );
            })}

            {customs.length > 0 && (
              <>
                <div className="my-1 border-t border-gray-100" />
                <p className="px-3 py-1 text-xs text-gray-400 font-medium">Custom Fields</p>
                {customs.map((col) => {
                  const isVisible = visibleKeys.includes(col.key);
                  return (
                    <div
                      key={col.key}
                      draggable={isVisible}
                      onDragStart={() => { dragKey.current = col.key; }}
                      onDragOver={(e) => { e.preventDefault(); }}
                      onDrop={() => { if (dragKey.current) reorder(dragKey.current, col.key); dragKey.current = null; }}
                      className="flex items-center gap-2 px-3 py-1.5 hover:bg-gray-50 cursor-grab"
                    >
                      {isVisible && <span className="text-gray-300 text-xs select-none">⠿</span>}
                      <label className="flex items-center gap-2 flex-1 cursor-pointer">
                        <input
                          type="checkbox"
                          checked={isVisible}
                          onChange={() => toggle(col.key)}
                          className="rounded border-gray-300 text-brand-600 focus:ring-brand-500"
                        />
                        <span className="text-sm text-gray-700">{col.label}</span>
                      </label>
                    </div>
                  );
                })}
              </>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
