import type { Accessor, JSX } from "solid-js";
import { createContext, useContext } from "solid-js";
import type { ListNavigationState } from "../../primitives/create-list-navigation";

/** Internal context shared between all Select sub-components. */
export interface InternalSelectContextValue {
  isOpen: Accessor<boolean>;
  open: () => void;
  close: () => void;
  toggle: () => void;
  navigation: ListNavigationState;
  triggerRef: Accessor<HTMLElement | null>;
  setTriggerRef: (el: HTMLElement | null) => void;
  contentRef: Accessor<HTMLElement | null>;
  setContentRef: (el: HTMLElement | null) => void;
  selectedValue: Accessor<string | undefined>;
  onSelect: (value: string) => void;
  disabled: Accessor<boolean>;
  required: Accessor<boolean>;
  name: Accessor<string | undefined>;
  contentId: string;
  triggerId: string;
  floatingStyle: Accessor<JSX.CSSProperties>;
}

const InternalSelectContext = createContext<InternalSelectContextValue>();

/**
 * Returns the internal Select context. Throws if used outside Select.
 */
export function useInternalSelectContext(): InternalSelectContextValue {
  const ctx = useContext(InternalSelectContext);
  if (!ctx) {
    throw new Error(
      "[PettyUI] Select parts must be used inside <Select>.\n" +
        "  Fix: <Select items={[...]}>\n" +
        "         <Select.Trigger>...</Select.Trigger>\n" +
        "         <Select.Content>\n" +
        '           <Select.Item value="a">A</Select.Item>\n' +
        "         </Select.Content>\n" +
        "       </Select>",
    );
  }
  return ctx;
}

export const InternalSelectContextProvider = InternalSelectContext.Provider;

/** Public context exposed via Select.useContext(). */
export interface SelectContextValue {
  /** Currently selected value. */
  value: Accessor<string | undefined>;
  /** Whether the select dropdown is open. */
  open: Accessor<boolean>;
}

const SelectContext = createContext<SelectContextValue>();

/**
 * Returns the public Select context. Throws if used outside Select.
 */
export function useSelectContext(): SelectContextValue {
  const ctx = useContext(SelectContext);
  if (!ctx) {
    throw new Error("[PettyUI] Select.useContext() called outside of <Select>.");
  }
  return ctx;
}

export const SelectContextProvider = SelectContext.Provider;
