import { useEffect, useRef, useState } from "react";
import styles from "./functionSelector.module.css";
import { getFileNameFromPath } from "@codeflash/shared";
import type { FileInWorkspace } from "@codeflash/types";

interface FunctionSelectorProps {
  files: FileInWorkspace[];
  functions: string[];
  selectedFile: string | undefined;
  selectedFunction: string | undefined;
  onFileSelect: (file: FileInWorkspace) => void;
  onFunctionSelect: (fn: string) => void;
  onFileRemove: () => void;
  onFunctionRemove: () => void;
  disabled?: boolean;
}

const getMinimalPath = (path: string) => {
  const parts = path.split("/");
  return parts.length > 2 ? parts.slice(-2).join("/") : path;
};

const FunctionSelector: React.FC<FunctionSelectorProps> = ({
  files,
  functions,
  selectedFile,
  selectedFunction,
  onFileSelect,
  onFunctionSelect,
  onFileRemove,
  onFunctionRemove,
  disabled = false,
}) => {
  const [fileDropdownOpen, setFileDropdownOpen] = useState(false);
  const [functionDropdownOpen, setFunctionDropdownOpen] = useState(false);
  const [fileSearch, setFileSearch] = useState("");
  const [functionSearch, setFunctionSearch] = useState("");
  const [selectedIndex, setSelectedIndex] = useState(0);

  const fileDropdownRef = useRef<HTMLDivElement>(null);
  const functionDropdownRef = useRef<HTMLDivElement>(null);
  const fileSearchRef = useRef<HTMLInputElement>(null);
  const functionSearchRef = useRef<HTMLInputElement>(null);

  // Close dropdowns when clicking outside
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (
        fileDropdownRef.current &&
        !fileDropdownRef.current.contains(e.target as Node)
      ) {
        setFileDropdownOpen(false);
        setFileSearch("");
      }
      if (
        functionDropdownRef.current &&
        !functionDropdownRef.current.contains(e.target as Node)
      ) {
        setFunctionDropdownOpen(false);
        setFunctionSearch("");
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  // Focus search input when dropdown opens
  useEffect(() => {
    if (fileDropdownOpen && fileSearchRef.current) {
      fileSearchRef.current.focus();
    }
  }, [fileDropdownOpen]);

  useEffect(() => {
    if (functionDropdownOpen && functionSearchRef.current) {
      functionSearchRef.current.focus();
    }
  }, [functionDropdownOpen]);

  // Reset selected index when search changes
  useEffect(() => {
    setSelectedIndex(0);
  }, [fileSearch, functionSearch]);

  const filteredFiles = fileSearch
    ? files.filter((f) =>
        getFileNameFromPath(f.rel)
          ?.toLowerCase()
          .includes(fileSearch.toLowerCase()),
      )
    : files;

  const filteredFunctions = functionSearch
    ? functions.filter((f) =>
        f.toLowerCase().includes(functionSearch.toLowerCase()),
      )
    : functions;

  const handleFileKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setSelectedIndex((prev) => Math.min(prev + 1, filteredFiles.length - 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setSelectedIndex((prev) => Math.max(prev - 1, 0));
    } else if (e.key === "Enter" && filteredFiles[selectedIndex]) {
      e.preventDefault();
      handleFileSelect(filteredFiles[selectedIndex]);
    } else if (e.key === "Escape") {
      setFileDropdownOpen(false);
      setFileSearch("");
    }
  };

  const handleFunctionKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setSelectedIndex((prev) =>
        Math.min(prev + 1, filteredFunctions.length - 1),
      );
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setSelectedIndex((prev) => Math.max(prev - 1, 0));
    } else if (e.key === "Enter" && filteredFunctions[selectedIndex]) {
      e.preventDefault();
      handleFunctionSelect(filteredFunctions[selectedIndex]);
    } else if (e.key === "Escape") {
      setFunctionDropdownOpen(false);
      setFunctionSearch("");
    }
  };

  const handleFileSelect = (file: FileInWorkspace) => {
    onFileSelect(file);
    setFileDropdownOpen(false);
    setFileSearch("");
    setSelectedIndex(0);
  };

  const handleFunctionSelect = (fn: string) => {
    onFunctionSelect(fn);
    setFunctionDropdownOpen(false);
    setFunctionSearch("");
    setSelectedIndex(0);
  };

  return (
    <div className={styles.selectorContainer}>
      {/* File Selector */}
      <div className={styles.selectorRow}>
        <div className={styles.selectorLabel}>
          <span className="codicon codicon-file-code"></span>
          <span>File</span>
        </div>
        <div className={styles.selectorWrapper} ref={fileDropdownRef}>
          <button
            type="button"
            className={`${styles.selectorButton} ${selectedFile ? styles.selected : ""}`}
            onClick={() => !disabled && setFileDropdownOpen(!fileDropdownOpen)}
            disabled={disabled}
          >
            {selectedFile ? (
              <>
                <span className="codicon codicon-python"></span>
                <span className={styles.selectedValue}>
                  {getFileNameFromPath(selectedFile)}
                </span>
                <button
                  type="button"
                  className={styles.clearButton}
                  onClick={(e) => {
                    e.stopPropagation();
                    onFileRemove();
                  }}
                >
                  <span className="codicon codicon-close"></span>
                </button>
              </>
            ) : (
              <>
                <span className={styles.placeholder}>Select a Python file</span>
                <span className="codicon codicon-chevron-down"></span>
              </>
            )}
          </button>

          {fileDropdownOpen && (
            <div className={styles.dropdown}>
              <div className={styles.searchWrapper}>
                <span className="codicon codicon-search"></span>
                <input
                  ref={fileSearchRef}
                  type="text"
                  className={styles.searchInput}
                  placeholder="Search files..."
                  value={fileSearch}
                  onChange={(e) => setFileSearch(e.target.value)}
                  onKeyDown={handleFileKeyDown}
                />
              </div>
              <ul className={styles.dropdownList}>
                {filteredFiles.length === 0 ? (
                  <li className={styles.noResults}>No files found</li>
                ) : (
                  filteredFiles.map((file, i) => (
                    <li
                      key={file.abs}
                      className={`${styles.dropdownItem} ${i === selectedIndex ? styles.active : ""}`}
                      onClick={() => handleFileSelect(file)}
                    >
                      <span className="codicon codicon-python"></span>
                      <div className={styles.fileInfo}>
                        <span className={styles.fileName}>
                          {getFileNameFromPath(file.rel)}
                        </span>
                        <span className={styles.filePath}>
                          {getMinimalPath(file.rel)}
                        </span>
                      </div>
                    </li>
                  ))
                )}
              </ul>
            </div>
          )}
        </div>
      </div>

      {/* Function Selector */}
      <div className={styles.selectorRow}>
        <div className={styles.selectorLabel}>
          <span className="codicon codicon-symbol-method"></span>
          <span>Function/Method</span>
        </div>
        <div className={styles.selectorWrapper} ref={functionDropdownRef}>
          <button
            type="button"
            className={`${styles.selectorButton} ${selectedFunction ? styles.selected : ""}`}
            onClick={() =>
              !disabled &&
              selectedFile &&
              setFunctionDropdownOpen(!functionDropdownOpen)
            }
            disabled={disabled || !selectedFile}
          >
            {selectedFunction ? (
              <>
                <span className="codicon codicon-symbol-method"></span>
                <span className={styles.selectedValue}>{selectedFunction}</span>
                <button
                  type="button"
                  className={styles.clearButton}
                  onClick={(e) => {
                    e.stopPropagation();
                    onFunctionRemove();
                  }}
                >
                  <span className="codicon codicon-close"></span>
                </button>
              </>
            ) : (
              <>
                <span className={styles.placeholder}>
                  {selectedFile
                    ? functions.length > 0
                      ? "Select a qualified name"
                      : "Loading functions..."
                    : "Select a file first"}
                </span>
                <span className="codicon codicon-chevron-down"></span>
              </>
            )}
          </button>

          {functionDropdownOpen && functions.length > 0 && (
            <div className={styles.dropdown}>
              <div className={styles.searchWrapper}>
                <span className="codicon codicon-search"></span>
                <input
                  ref={functionSearchRef}
                  type="text"
                  className={styles.searchInput}
                  placeholder="Search qualified names..."
                  value={functionSearch}
                  onChange={(e) => setFunctionSearch(e.target.value)}
                  onKeyDown={handleFunctionKeyDown}
                />
              </div>
              <ul className={styles.dropdownList}>
                {filteredFunctions.length === 0 ? (
                  <li className={styles.noResults}>No functions found</li>
                ) : (
                  filteredFunctions.map((fn, i) => (
                    <li
                      key={fn}
                      className={`${styles.dropdownItem} ${i === selectedIndex ? styles.active : ""}`}
                      onClick={() => handleFunctionSelect(fn)}
                    >
                      <span className="codicon codicon-symbol-method"></span>
                      <span>{fn}</span>
                    </li>
                  ))
                )}
              </ul>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default FunctionSelector;
