import React, { useState, useEffect, useRef } from "react";
import { useFormContext } from "react-hook-form";
import { createPortal } from "react-dom";
import "./MultiSelectDropdown.css";

const SelectMultiple = ({
  name,
  options = [],
  label = "Select options",
  labelKey = "name", // Can now be a function or a string
  valueKey = "id",
  placeholder = "Please select...",
  IsLoading = false,
}) => {
  const { setValue, watch } = useFormContext();
  const selectedValues = watch(name) || [];

  const [isOpen, setIsOpen] = useState(false);
  const [searchText, setSearchText] = useState("");
  const containerRef = useRef(null);
  const dropdownRef = useRef(null);

  const [dropdownStyles, setDropdownStyles] = useState({ top: 0, left: 0, width: 0 });

  useEffect(() => {
    const handleClickOutside = (e) => {
      if (
        containerRef.current &&
        !containerRef.current.contains(e.target) &&
        (!dropdownRef.current || !dropdownRef.current.contains(e.target))
      ) {
        setIsOpen(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  useEffect(() => {
    if (isOpen && containerRef.current) {
      const rect = containerRef.current.getBoundingClientRect();
      setDropdownStyles({
        top: rect.bottom + window.scrollY,
        left: rect.left + window.scrollX,
        width: rect.width,
      });
    }
  }, [isOpen]);

  const getLabel = (item) => {
    return typeof labelKey === "function" ? labelKey(item) : item[labelKey];
  };

  const handleCheckboxChange = (value) => {
    const updated = selectedValues.includes(value)
      ? selectedValues.filter((v) => v !== value)
      : [...selectedValues, value];

    setValue(name, updated, { shouldValidate: true });
  };

  const filteredOptions = options.filter((item) => {
    const label = getLabel(item);
    return label?.toLowerCase().includes(searchText.toLowerCase());
  });

  const dropdownElement = (
    <div
      ref={dropdownRef}
      className="multi-select-dropdown-options py-2"
      style={{
        position: "absolute",
        top: dropdownStyles.top,
        left: dropdownStyles.left,
        width: dropdownStyles.width,
        zIndex: 9999,
        backgroundColor: "white",
        boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
        borderRadius: 4,
        maxHeight: 300,
        overflowY: "auto",
      }}
    >
      <div className="multi-select-dropdown-search" style={{ padding: 8 }}>
        <input
          type="text"
          placeholder="Search..."
          value={searchText}
          onChange={(e) => setSearchText(e.target.value)}
          className="multi-select-dropdown-search-input"
          style={{ width: "100%", padding: 4 }}
        />
      </div>

      {filteredOptions.map((item) => {
        const labelVal = getLabel(item);
        const valueVal = item[valueKey];
        const isChecked = selectedValues.includes(valueVal);

        return (
          <div
            key={valueVal}
            className={`multi-select-dropdown-option ${isChecked ? "selected" : ""}`}
            style={{ display: "flex", alignItems: "center", padding: "4px 8px" }}
          >
            <input
              type="checkbox"
              className="custom-checkbox form-check-input"
              checked={isChecked}
              onChange={() => handleCheckboxChange(valueVal)}
              style={{ marginRight: 8 }}
            />
            <label className="text-secondary">{labelVal}</label>
          </div>
        );
      })}

      {!IsLoading && filteredOptions.length === 0 && (
        <div className="multi-select-dropdown-Not-found" style={{ padding: 8 }}>
          <label className="text-muted">Not Found {`'${searchText}'`}</label>
        </div>
      )}
      {IsLoading && filteredOptions.length === 0 && (
        <div className="multi-select-dropdown-Not-found" style={{ padding: 8 }}>
          <label className="text-muted">Loading...</label>
        </div>
      )}
    </div>
  );

  return (
    <>
      <div ref={containerRef} className="multi-select-dropdown-container" style={{ position: "relative" }}>
        <label className="form-label mb-1">{label}</label>

        <div
          className="multi-select-dropdown-header"
          onClick={() => setIsOpen((prev) => !prev)}
          style={{ cursor: "pointer" }}
        >
          <span
            className={
              selectedValues.length > 0 ? "placeholder-style-selected" : "placeholder-style"
            }
          >
            <div className="selected-badges-container">
              {selectedValues.length > 0 ? (
                selectedValues.map((val) => {
                  const found = options.find((opt) => opt[valueKey] === val);
                  const label = found ? getLabel(found) : "";
                  return (
                    <span key={val} className="badge badge-selected-item mx-1 mb-1">
                      {label}
                    </span>
                  );
                })
              ) : (
                <span className="placeholder-text">{placeholder}</span>
              )}
            </div>
          </span>
          <i className="bx bx-chevron-down"></i>
        </div>
      </div>

      {isOpen && createPortal(dropdownElement, document.body)}
    </>
  );
};

export default SelectMultiple;
