"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { ExplanationUiFont } from "./explanation-ui-font";
import type { QuestionField } from "@/lib/schema-adapter";
import { useI18n } from "@/translations/provider";
import { useQuestionAnswers } from "./question-answer-storage";
import QuestionTitle from "./question-title";

type QuestionDropdownProps = {
  question: QuestionField;
  disabled?: boolean;
};

export function QuestionDropdown({
  question,
  disabled,
}: QuestionDropdownProps) {
  const { dictionary: t } = useI18n();
  const { getAnswerValue, setAnswerValue } = useQuestionAnswers();
  const rawValue = getAnswerValue(question);

  const isMulti =
    Array.isArray(rawValue) ||
    question.type === "checkbox" ||
    (question.extras?.range && question.extras.range[1] > 1);
    
  const selectedList = Array.isArray(rawValue)
    ? rawValue
    : typeof rawValue === "string" && rawValue
      ? [rawValue]
      : [];
  const singleValue = typeof rawValue === "string" ? rawValue : "";

  const [isOpen, setIsOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const containerRef = useRef<HTMLDivElement>(null);
  const listRef = useRef<HTMLDivElement>(null);
  const searchInputRef = useRef<HTMLInputElement>(null);

  // Lock page scroll when dropdown is open
  useEffect(() => {
    if (isOpen) {
      document.body.classList.add("dropdown-open");
      document.body.style.overflow = "hidden";
      document.documentElement.style.overflow = "hidden";
    } else {
      document.body.classList.remove("dropdown-open");
      document.body.style.overflow = "";
      document.documentElement.style.overflow = "";
    }
    return () => {
      document.body.classList.remove("dropdown-open");
      document.body.style.overflow = "";
      document.documentElement.style.overflow = "";
    };
  }, [isOpen]);

  // Prevent wheel scroll from escaping the options list
  const handleListWheel = useCallback((e: React.WheelEvent<HTMLDivElement>) => {
    e.stopPropagation();
    const el = listRef.current;
    if (!el) return;

    const atTop = el.scrollTop <= 0 && e.deltaY < 0;
    const atBottom =
      el.scrollTop + el.clientHeight >= el.scrollHeight && e.deltaY > 0;

    if (atTop || atBottom) {
      e.preventDefault();
    }
  }, []);

  // Close dropdown on click outside
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (
        containerRef.current &&
        !containerRef.current.contains(event.target as Node)
      ) {
        setIsOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, []);

  useEffect(() => {
    if (isOpen) {
      const timer = setTimeout(() => {
        searchInputRef.current?.focus();
      }, 50);
      return () => clearTimeout(timer);
    }
  }, [isOpen]);

  const options = question.options || [];

  const showSearch = (() => {
    if (question.extras?.noSearch) return false;
    return options.length > 10;
  })();

  const filteredOptions = options.filter((option) =>
    option.label.toLowerCase().includes(searchQuery.toLowerCase()),
  );

  const getCleanLabel = (optId: string) => {
    const opt = options.find((o) => o.id === optId);
    if (!opt) return optId;
    return opt.label.split(" - ")[0];
  };

  const displayLabel = isMulti
    ? selectedList.length > 0
      ? selectedList.map(getCleanLabel).join(", ")
      : question.extras?.placeHolder || "Select"
    : singleValue
      ? getCleanLabel(singleValue)
      : question.extras?.placeHolder || "Select";

  const hasSelectedValue = isMulti
    ? selectedList.length > 0
    : Boolean(singleValue);

  const toggleMultiOption = (optionId: string) => {
    let nextValue: string[];

    if (selectedList.includes(optionId)) {
      nextValue = selectedList.filter((v) => v !== optionId);
    } else {
      nextValue = [...selectedList, optionId];
    }

    setAnswerValue(
      question, nextValue.length > 0 ? nextValue : null,
    );
  };

  return (
    <div
      ref={containerRef}
      className={[
        "relative flex w-full flex-col gap-2.5 transition-opacity duration-200",
        disabled ? "pointer-events-none opacity-30" : "",
      ].join(" ")}
    >
      <QuestionTitle question={question} />

      {/* Select Trigger Button */}
      <button
        type="button"
        disabled={disabled}
        onClick={() => setIsOpen(!isOpen)}
        className={[
          "flex h-[54px] w-full items-center justify-between rounded-[16px] border bg-white px-4.5 text-start transition-all cursor-pointer outline-none",
          isOpen
            ? "border-[#6F6F6F] ring-1 ring-[#6F6F6F]"
            : "border-[#D0D5DD] hover:border-[#98A2B3]",
        ].join(" ")}
      >
        <span
          className={[
            "text-[15px] font-medium truncate",
            hasSelectedValue ? "text-[#181818]" : "text-[#667085]",
          ].join(" ")}
        >
          {displayLabel}
        </span>
        <svg
          aria-hidden="true"
          width="16"
          height="10"
          viewBox="0 0 16 10"
          fill="none"
          className={[
            "shrink-0 transition-transform duration-200",
            isOpen ? "rotate-180" : "",
          ].join(" ")}
        >
          <path
            d="M14.75 1.25L7.75 8.25L0.75 1.25"
            stroke="#344054"
            strokeWidth="1.75"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        </svg>
      </button>

      {/* Dropdown Options Panel */}
      {isOpen && (
        <div className="absolute top-[calc(100%+8px)] left-0 z-50 flex w-full flex-col gap-3.5 rounded-[20px] bg-white p-4.5 shadow-[0_12px_36px_rgba(0,0,0,0.09)] border border-[#EAECF0] animate-in fade-in zoom-in-95 duration-150">
          {/* Search Input Bar */}
          {showSearch ? (
            <div className="flex h-[46px] w-full items-center gap-2.5 rounded-[12px] bg-[#EFEFEF] px-3.5 transition-colors focus-within:bg-[#E8E8E8]">
              <svg
                aria-hidden="true"
                width="18"
                height="18"
                viewBox="0 0 18 18"
                fill="none"
                className="shrink-0 text-[#667085]"
              >
                <path
                  d="M8.25 14.25C11.5637 14.25 14.25 11.5637 14.25 8.25C14.25 4.93629 11.5637 2.25 8.25 2.25C4.93629 2.25 2.25 4.93629 2.25 8.25C2.25 11.5637 4.93629 14.25 8.25 14.25Z"
                  stroke="#667085"
                  strokeWidth="1.75"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                />
                <path
                  d="M15.75 15.75L12.5 12.5"
                  stroke="#667085"
                  strokeWidth="1.75"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                />
              </svg>
              <input
                ref={searchInputRef}
                type="text"
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                placeholder="Search..."
                className="flex-1 bg-transparent text-[14px] font-medium text-[#181818] outline-none placeholder:text-[#98A2B3]"
              />
              {searchQuery ? (
                <button
                  type="button"
                  onClick={() => setSearchQuery("")}
                  className="text-[#667085] hover:text-[#181818] text-xs font-semibold"
                >
                  ✕
                </button>
              ) : null}
            </div>
          ) : null}

          {/* Options List */}
          <div
            ref={listRef}
            onWheel={handleListWheel}
            onTouchStart={(e) => e.stopPropagation()}
            onTouchMove={(e) => e.stopPropagation()}
            onTouchEnd={(e) => e.stopPropagation()}
            className="flex max-h-[220px] flex-col gap-3.5 overflow-y-auto overscroll-contain pr-1"
          >
            {filteredOptions.length > 0 ? (
              filteredOptions.map((option) => {
                const isSelected = isMulti
                  ? selectedList.includes(option.id)
                  : singleValue === option.id;

                return (
                  <button
                    key={option.id}
                    type="button"
                    onClick={() => {
                      if (isMulti) {
                        toggleMultiOption(option.id);
                      } else {
                        setAnswerValue(question, option.id);
                        setIsOpen(false);
                      }
                    }}
                    className="flex w-full items-start gap-3 text-start cursor-pointer group/opt py-0.5"
                  >
                    {/* Option Indicator Icon */}
                    {isMulti ? (
                      /* Multi-select / Checkbox style */
                      <div
                        className={[
                          "size-[20px] shrink-0 rounded-[6px] transition-all duration-150 mt-0.5",
                          isSelected
                            ? "bg-[#F2465F] shadow-xs"
                            : "border-[2px] border-[#344054] bg-transparent group-hover/opt:border-[#181818]",
                        ].join(" ")}
                      />
                    ) : (
                      /* Single-select / Radio style */
                      <div
                        className={[
                          "size-[20px] shrink-0 rounded-full transition-all duration-150 mt-0.5",
                          isSelected
                            ? "bg-[#F2465F] shadow-xs"
                            : "border-[2px] border-[#344054] bg-transparent group-hover/opt:border-[#181818]",
                        ].join(" ")}
                      />
                    )}

                    <span className="text-[15px] text-[#181818] leading-tight flex-1">
                      {option.label.includes(" - ") ? (
                        (() => {
                          const parts = option.label.split(" - ");
                          const title = parts[0];
                          const description = parts.slice(1).join(" - ");
                          return (
                            <span className="flex flex-col gap-1 text-start">
                              <span className="font-bold text-[#181818]">
                                {title}
                              </span>
                              <ExplanationUiFont>
                                {description}
                              </ExplanationUiFont>
                            </span>
                          );
                        })()
                      ) : (
                        <span className="font-bold">{option.label}</span>
                      )}
                    </span>
                  </button>
                );
              })
            ) : (
              <span className="py-2 text-[13px] text-[#667085]">
                No options found
              </span>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

export default QuestionDropdown;
