import React, { useState, useEffect, useRef, useCallback } from "react";
import { __ } from "@wordpress/i18n";
import { buildUrl } from "@libs/url";
import { Search, X, ChevronDown, Loader2 } from "lucide-react";

const getSelectedScopeIds = (products) =>
  Array.from(
    new Set(
      products.flatMap((product) =>
        Array.isArray(product.scope_ids) ? product.scope_ids : [],
      ),
    ),
  );

const RetentionFilters = ({
  startDate,
  endDate,
  productIds,
  onFilterChange,
  apiBaseUrl,
  nonce,
}) => {
  const [productSearch, setProductSearch] = useState("");
  const [productOptions, setProductOptions] = useState([]);
  const [selectedProducts, setSelectedProducts] = useState([]);
  const [productLoading, setProductLoading] = useState(false);
  const [dropdownOpen, setDropdownOpen] = useState(false);

  const searchTimeout = useRef(null);
  const abortRef = useRef(null);
  const dropdownRef = useRef(null);

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

  const searchProducts = useCallback(
    async (term) => {
      if (abortRef.current) {
        abortRef.current.abort();
      }

      if (!term || term.length < 2) {
        setProductOptions([]);
        return;
      }

      const controller = new AbortController();
      abortRef.current = controller;
      setProductLoading(true);

      try {
        const url = buildUrl(
          `${apiBaseUrl}arraysubs/v1/retention-analytics/products`,
          { search: term },
        );

        const response = await fetch(url, {
          headers: { "X-WP-Nonce": nonce },
          signal: controller.signal,
        });

        if (!response.ok) {
          throw new Error("Search failed");
        }

        const result = await response.json();
        const items = result.content || result;

        setProductOptions(
          Array.isArray(items)
            ? items.filter(
                (item) =>
                  !selectedProducts.some((sp) => sp.value === item.value),
              )
            : [],
        );
      } catch (error) {
        if (error.name !== "AbortError") {
          setProductOptions([]);
        }
      } finally {
        setProductLoading(false);
      }
    },
    [apiBaseUrl, nonce, selectedProducts],
  );

  const handleProductSearch = (value) => {
    setProductSearch(value);

    if (searchTimeout.current) {
      clearTimeout(searchTimeout.current);
    }

    searchTimeout.current = setTimeout(() => {
      searchProducts(value);
    }, 300);
  };

  const selectProduct = (product) => {
    const updated = [...selectedProducts, product];
    setSelectedProducts(updated);
    setProductOptions((prev) => prev.filter((p) => p.value !== product.value));
    setProductSearch("");

    onFilterChange({ productIds: getSelectedScopeIds(updated) });
  };

  const removeProduct = (productValue) => {
    const updated = selectedProducts.filter((p) => p.value !== productValue);
    setSelectedProducts(updated);
    onFilterChange({ productIds: getSelectedScopeIds(updated) });
  };

  const clearProducts = () => {
    setSelectedProducts([]);
    setProductSearch("");
    setProductOptions([]);
    onFilterChange({ productIds: [] });
  };

  return (
    <div className="arraysubs-retention-filters">
      <div className="arraysubs-retention-filters__group">
        <label
          className="arraysubs-retention-filters__label"
          htmlFor="retention-start-date"
        >
          {__("Start Date", "arraysubs")}
        </label>
        <input
          id="retention-start-date"
          type="date"
          className="arraysubs-retention-filters__date"
          value={startDate}
          max={endDate}
          onChange={(e) => onFilterChange({ startDate: e.target.value })}
        />
      </div>

      <div className="arraysubs-retention-filters__group">
        <label
          className="arraysubs-retention-filters__label"
          htmlFor="retention-end-date"
        >
          {__("End Date", "arraysubs")}
        </label>
        <input
          id="retention-end-date"
          type="date"
          className="arraysubs-retention-filters__date"
          value={endDate}
          min={startDate}
          onChange={(e) => onFilterChange({ endDate: e.target.value })}
        />
      </div>

      <div className="arraysubs-retention-filters__group arraysubs-retention-filters__group--product">
        <label className="arraysubs-retention-filters__label">
          {__("Products", "arraysubs")}
        </label>
        <div
          className="arraysubs-retention-filters__select-wrapper"
          ref={dropdownRef}
        >
          <div
            className={`arraysubs-retention-filters__select-control ${
              dropdownOpen
                ? "arraysubs-retention-filters__select-control--open"
                : ""
            }`}
            onClick={() => setDropdownOpen(!dropdownOpen)}
            onKeyDown={(e) => {
              if (e.key === "Enter" || e.key === " ") {
                setDropdownOpen(!dropdownOpen);
              }
            }}
            role="combobox"
            aria-expanded={dropdownOpen}
            tabIndex={0}
          >
            <div className="arraysubs-retention-filters__select-values">
              {selectedProducts.length === 0 && !dropdownOpen && (
                <span className="arraysubs-retention-filters__placeholder">
                  {__("All products", "arraysubs")}
                </span>
              )}
              {selectedProducts.map((product) => (
                <span
                  key={product.value}
                  className="arraysubs-retention-filters__tag"
                >
                  <span className="arraysubs-retention-filters__tag-label">
                    {product.label}
                  </span>
                  <button
                    type="button"
                    className="arraysubs-retention-filters__tag-remove"
                    onClick={(e) => {
                      e.stopPropagation();
                      removeProduct(product.value);
                    }}
                  >
                    <X size={12} />
                  </button>
                </span>
              ))}
            </div>
            <div className="arraysubs-retention-filters__select-icons">
              {selectedProducts.length > 0 && (
                <button
                  type="button"
                  className="arraysubs-retention-filters__clear-btn"
                  onClick={(e) => {
                    e.stopPropagation();
                    clearProducts();
                  }}
                >
                  <X size={14} />
                </button>
              )}
              <ChevronDown size={16} />
            </div>
          </div>

          {dropdownOpen && (
            <div className="arraysubs-retention-filters__dropdown">
              <div className="arraysubs-retention-filters__search-box">
                <Search size={14} />
                <input
                  type="text"
                  className="arraysubs-retention-filters__search-input"
                  placeholder={__("Search products…", "arraysubs")}
                  value={productSearch}
                  onChange={(e) => handleProductSearch(e.target.value)}
                  autoFocus
                />
                {productLoading && (
                  <Loader2
                    size={14}
                    className="arraysubs-retention-filters__spinner"
                  />
                )}
              </div>

              <ul className="arraysubs-retention-filters__options">
                {productOptions.length === 0 && !productLoading && (
                  <li className="arraysubs-retention-filters__option--empty">
                    {productSearch.length < 2
                      ? __("Type to search…", "arraysubs")
                      : __("No products found", "arraysubs")}
                  </li>
                )}
                {productOptions.map((option) => (
                  <li
                    key={option.value}
                    className="arraysubs-retention-filters__option"
                    onClick={() => selectProduct(option)}
                    onKeyDown={(e) => {
                      if (e.key === "Enter") selectProduct(option);
                    }}
                    role="option"
                    tabIndex={0}
                  >
                    {option.label}
                  </li>
                ))}
              </ul>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default RetentionFilters;
