import type { JSX } from "solid-js";
import { splitProps } from "solid-js";
import { useInternalComboboxContext } from "./combobox-context";

export interface ComboboxInputProps extends JSX.InputHTMLAttributes<HTMLInputElement> {
  children?: JSX.Element | undefined;
}

/**
 * Input element for Combobox. Has role="combobox" and handles typing,
 * arrow-key navigation, Enter selection, and Escape to close.
 */
export function ComboboxInput(props: ComboboxInputProps): JSX.Element {
  const [local, rest] = splitProps(props, ["onInput", "onKeyDown", "children"]);
  const ctx = useInternalComboboxContext();

  const handleInput: JSX.EventHandler<HTMLInputElement, InputEvent> = (e) => {
    if (typeof local.onInput === "function") {
      (local.onInput as (e: InputEvent & { currentTarget: HTMLInputElement }) => void)(e);
    }
    const value = e.currentTarget.value;
    ctx.setInputValue(value);
    ctx.onInputChange?.(value);
    if (!ctx.isOpen()) ctx.open();
  };

  /** Handles Enter key: selects highlighted item or commits custom value. */
  function handleEnter(): void {
    const highlighted = ctx.navigation.highlightedValue();
    if (highlighted !== undefined) {
      ctx.onSelect(highlighted);
      return;
    }
    if (ctx.allowCustomValue() && ctx.inputValue() !== "") {
      ctx.navigation.clearHighlight();
      ctx.close();
      ctx.onCustomValue(ctx.inputValue());
    }
  }

  const handleKeyDown: JSX.EventHandler<HTMLInputElement, KeyboardEvent> = (e) => {
    if (typeof local.onKeyDown === "function") local.onKeyDown(e);
    if (ctx.disabled()) return;

    switch (e.key) {
      case "ArrowDown": {
        e.preventDefault();
        if (!ctx.isOpen()) ctx.open();
        ctx.navigation.containerProps.onKeyDown(e);
        break;
      }
      case "ArrowUp": {
        e.preventDefault();
        ctx.navigation.containerProps.onKeyDown(e);
        break;
      }
      case "Enter": {
        e.preventDefault();
        handleEnter();
        break;
      }
      case "Escape": {
        e.preventDefault();
        if (ctx.isOpen()) {
          ctx.close();
        } else {
          ctx.setInputValue("");
          ctx.onInputChange?.("");
        }
        break;
      }
      default:
        break;
    }
  };

  return (
    <input
      ref={(el) => ctx.setInputRef(el)}
      type="text"
      role="combobox"
      id={ctx.inputId}
      value={ctx.inputValue()}
      aria-expanded={ctx.isOpen()}
      aria-haspopup="listbox"
      aria-autocomplete="list"
      aria-controls={ctx.isOpen() ? ctx.contentId : undefined}
      aria-activedescendant={
        ctx.isOpen() ? ctx.navigation.containerProps["aria-activedescendant"] : undefined
      }
      data-state={ctx.isOpen() ? "open" : "closed"}
      disabled={ctx.disabled()}
      onInput={handleInput}
      onKeyDown={handleKeyDown}
      {...rest}
    />
  );
}
