import { useState, useMemo, useCallback, useRef, useEffect, type FC } from "react";
import { buildCountryCityRows } from "./buildCountryCityRows.js";
import type { IAirport, IDictionaries } from "@/shared/dictionaries/index.js";
import "./CityPickerPopup.scss";

export interface CityPickerPopupProps {
  dictionaries: IDictionaries;
  selectedCode?: string;
  onSelect: (code: string) => void;
  onLocate?: () => void | Promise<void>;
  onClose?: () => void;
}

/** A selectable entry flattened from all rows — used for keyboard navigation. */
interface FlatItem {
  code: string;
  /** DOM element ID used for aria-activedescendant */
  id: string;
}

export const CityPickerPopup: FC<CityPickerPopupProps> = ({
  dictionaries,
  selectedCode,
  onSelect,
  onLocate,
  onClose,
}) => {
  // TZ §4.1.9.2: "Россия и СНГ" direction pinned first; other directions
  // alphabetical by localized name. `localeCompare` gives locale-aware
  // collation; we detect the pinned direction by matching "Россия" /
  // "Russia" / "CIS" as substrings so minor name variations still match.
  const regions = useMemo(() => {
    const sorted = [...dictionaries.regions].sort((a, b) =>
      a.name.localeCompare(b.name),
    );
    const isCisName = (s: string): boolean => {
      const lower = s.toLowerCase();
      return (
        lower.includes("россия") ||
        lower.includes("russia") ||
        lower.includes("снг") ||
        lower.includes("cis")
      );
    };
    const cisIdx = sorted.findIndex((r) => isCisName(r.name));
    if (cisIdx > 0) {
      const [cis] = sorted.splice(cisIdx, 1);
      if (cis) sorted.unshift(cis);
    }
    return sorted;
  }, [dictionaries.regions]);
  const [activeRegionId, setActiveRegionId] = useState<number>(
    regions[0]?.id ?? 0,
  );
  const [highlightedIndex, setHighlightedIndex] = useState<number>(-1);
  const scrollPanelRef = useRef<HTMLDivElement>(null);

  const rows = useMemo(
    () => buildCountryCityRows(dictionaries, activeRegionId),
    [dictionaries, activeRegionId],
  );

  /** Ordered flat list of all selectable items in the current region. */
  const flatItems = useMemo<FlatItem[]>(() => {
    const items: FlatItem[] = [];
    for (const row of rows) {
      if (row.city1Airports && row.city1) {
        // multi-airport city
        items.push({ code: row.city1.code, id: `picker-item-${row.city1.code}` });
        for (const ap of row.city1Airports) {
          items.push({ code: ap.code, id: `picker-item-${ap.code}` });
        }
      } else {
        if (row.city1) items.push({ code: row.city1.code, id: `picker-item-${row.city1.code}` });
        if (row.city2) items.push({ code: row.city2.code, id: `picker-item-${row.city2.code}` });
      }
    }
    return items;
  }, [rows]);

  // Reset highlight when region changes
  useEffect(() => {
    setHighlightedIndex(-1);
  }, [activeRegionId]);

  // Scroll highlighted item into view
  useEffect(() => {
    if (highlightedIndex < 0 || !scrollPanelRef.current) return;
    const item = flatItems[highlightedIndex];
    if (!item) return;
    const el = scrollPanelRef.current.querySelector(`[data-item-id="${item.id}"]`);
    if (el && typeof (el as HTMLElement).scrollIntoView === "function") {
      (el as HTMLElement).scrollIntoView({ block: "nearest" });
    }
  }, [highlightedIndex, flatItems]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLDivElement>) => {
      if (e.key === "Escape") {
        e.preventDefault();
        e.stopPropagation();
        onClose?.();
        return;
      }
      if (e.key === "ArrowDown") {
        e.preventDefault();
        setHighlightedIndex((i) => Math.min(i + 1, flatItems.length - 1));
        return;
      }
      if (e.key === "ArrowUp") {
        e.preventDefault();
        setHighlightedIndex((i) => Math.max(i - 1, 0));
        return;
      }
      if (e.key === "Enter") {
        e.preventDefault();
        const item = flatItems[highlightedIndex];
        if (item) onSelect(item.code);
        return;
      }
    },
    [flatItems, highlightedIndex, onSelect, onClose],
  );

  const activeItemId =
    highlightedIndex >= 0 ? (flatItems[highlightedIndex]?.id ?? undefined) : undefined;

  return (
    <div
      className="city-autocomplete-popup"
      data-testid="city-picker-popup"
      role="dialog"
      aria-label="City picker"
      onKeyDown={handleKeyDown}
      tabIndex={-1}
    >
      <div className="tabs">
        {regions.map((r) => (
          <button
            key={r.id}
            type="button"
            role="tab"
            aria-selected={r.id === activeRegionId}
            className={`tab-button${r.id === activeRegionId ? " active" : ""}`}
            onClick={() => setActiveRegionId(r.id)}
            data-testid={`city-picker-tab-${r.id}`}
          >
            {r.name}
          </button>
        ))}
      </div>

      <div className="content">
        <div
          className="content--scroll-panel"
          ref={scrollPanelRef}
          aria-activedescendant={activeItemId}
        >
          {rows.map((row, idx) => {
            const rowKey = `${row.countryName ?? ""}-${row.city1?.code ?? ""}-${idx}`;
            const isMulti = Boolean(row.city1Airports);
            const city1 = row.city1;
            const city2 = row.city2;
            const city1Airports = row.city1Airports;

            const itemId1 = city1 ? `picker-item-${city1.code}` : undefined;
            const itemId2 = city2 ? `picker-item-${city2.code}` : undefined;
            const isHighlighted1 = itemId1 !== undefined && itemId1 === activeItemId;
            const isHighlighted2 = itemId2 !== undefined && itemId2 === activeItemId;

            return (
              <div
                key={rowKey}
                className={`row${row.countryName ? " country-start-row" : ""}`}
              >
                <div className="cell contry">
                  <div>{row.countryName ?? ""}</div>
                </div>

                {!isMulti && city1 && (
                  <>
                    <div
                      className={`cell city${city1.code === selectedCode ? " city-active" : ""}${isHighlighted1 ? " city-highlighted" : ""}`}
                      data-testid={`city-name-cell-${city1.name}`}
                    >
                      <div
                        id={itemId1}
                        data-item-id={itemId1}
                        className="city--item"
                        role="option"
                        aria-selected={city1.code === selectedCode}
                        tabIndex={0}
                        onClick={() => onSelect(city1.code)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter" || e.key === " ") onSelect(city1.code);
                        }}
                      >
                        {city1.name}
                      </div>
                    </div>
                    <div className={`cell city${city2?.code === selectedCode ? " city-active" : ""}${isHighlighted2 ? " city-highlighted" : ""}`}>
                      {city2 && (
                        <div
                          id={itemId2}
                          data-item-id={itemId2}
                          className="city--item"
                          role="option"
                          aria-selected={city2.code === selectedCode}
                          tabIndex={0}
                          data-testid={`city-name-cell-${city2.name}`}
                          onClick={() => onSelect(city2.code)}
                          onKeyDown={(e) => {
                            if (e.key === "Enter" || e.key === " ") onSelect(city2.code);
                          }}
                        >
                          {city2.name}
                        </div>
                      )}
                    </div>
                  </>
                )}

                {isMulti && city1 && city1Airports && (
                  <div className={`cell city${city1.code === selectedCode ? " city-active" : ""}${isHighlighted1 ? " city-highlighted" : ""}`}>
                    <div
                      id={itemId1}
                      data-item-id={itemId1}
                      className="city--item"
                      role="option"
                      aria-selected={city1.code === selectedCode}
                      tabIndex={0}
                      data-testid={`city-name-cell-${city1.name}`}
                      onClick={() => onSelect(city1.code)}
                      onKeyDown={(e) => {
                        if (e.key === "Enter" || e.key === " ") onSelect(city1.code);
                      }}
                    >
                      {city1.name}
                    </div>
                    <div className="airports-column">
                      {city1Airports.map((ap: IAirport) => {
                        const apId = `picker-item-${ap.code}`;
                        const isApHighlighted = apId === activeItemId;
                        return (
                          <div
                            key={ap.code}
                            id={apId}
                            data-item-id={apId}
                            title={ap.name}
                            className={`city--item${isApHighlighted ? " city--item-highlighted" : ""}`}
                            role="option"
                            aria-selected={ap.code === selectedCode}
                            tabIndex={0}
                            data-testid={`airport-name-cell-${ap.name}`}
                            onClick={() => onSelect(ap.code)}
                            onKeyDown={(e) => {
                              if (e.key === "Enter" || e.key === " ") onSelect(ap.code);
                            }}
                          >
                            {ap.name}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>

      {onLocate && (
        <div className="city-autocomplete-popup-footer">
          <div className="gps-contaner">
            <button
              type="button"
              className="gps-button color blue-light"
              onClick={() => void onLocate()}
              data-testid="city-picker-locate"
            >
              GPS
            </button>
          </div>
        </div>
      )}
    </div>
  );
};
