"use client";

import { useEffect, useMemo, useState } from "react";

type SearchableSelectFieldProps = {
  label: string;
  value: string;
  onChange: (value: string) => void;
  options: Array<{ value: string; label: string }>;
  placeholder: string;
  searchPlaceholder?: string;
  disabled?: boolean;
};

export function SearchableSelectField({
  label,
  value,
  onChange,
  options,
  placeholder,
  searchPlaceholder,
  disabled = false
}: SearchableSelectFieldProps) {
  const [search, setSearch] = useState("");
  const [isOpen, setIsOpen] = useState(false);

  const selectedOption = options.find((option) => option.value === value) ?? null;

  useEffect(() => {
    if (!selectedOption) {
      if (!value) setSearch("");
      return;
    }
    setSearch(selectedOption.label);
  }, [selectedOption, value]);

  const filteredOptions = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    if (!keyword) return options;
    return options.filter((option) => option.label.toLowerCase().includes(keyword));
  }, [options, search]);

  function handleSelect(nextValue: string) {
    const nextOption = options.find((option) => option.value === nextValue) ?? null;
    onChange(nextValue);
    setSearch(nextOption?.label ?? "");
    setIsOpen(false);
  }

  return (
    <label className="block">
      <span className="ops-label">{label}</span>
      <div className="relative">
        <input
          value={search}
          disabled={disabled}
          onFocus={() => setIsOpen(true)}
          onChange={(event) => {
            setSearch(event.target.value);
            setIsOpen(true);
            if (value) onChange("");
          }}
          onBlur={() => {
            window.setTimeout(() => {
              setIsOpen(false);
              if (!value) return;
              const currentSelected = options.find((option) => option.value === value);
              if (currentSelected) setSearch(currentSelected.label);
            }, 120);
          }}
          className="ops-input"
          placeholder={searchPlaceholder ?? placeholder}
        />
        <input type="hidden" value={value} readOnly />
        {isOpen && !disabled ? (
          <div className="absolute left-0 right-0 z-20 mt-2 overflow-hidden rounded-xl border border-line bg-white shadow-lg">
            <button
              type="button"
              onMouseDown={(event) => {
                event.preventDefault();
                handleSelect("");
              }}
              className="block w-full border-b border-line/70 px-4 py-3 text-left text-sm text-slate-500 hover:bg-slate-50"
            >
              {placeholder}
            </button>
            {filteredOptions.length === 0 ? (
              <div className="px-4 py-3 text-sm text-slate-500">Tidak ada opsi yang cocok.</div>
            ) : (
              <div className="max-h-64 overflow-y-auto">
                {filteredOptions.map((option) => (
                  <button
                    key={option.value}
                    type="button"
                    onMouseDown={(event) => {
                      event.preventDefault();
                      handleSelect(option.value);
                    }}
                    className={`block w-full px-4 py-3 text-left text-sm hover:bg-slate-50 ${
                      value === option.value ? "bg-slate-100 font-medium text-ink" : "text-slate-700"
                    }`}
                  >
                    {option.label}
                  </button>
                ))}
              </div>
            )}
          </div>
        ) : null}
      </div>
    </label>
  );
}
