import { customElement, noShadowDOM } from "solid-element";
import { onMount, onCleanup, Show, createResource } from "solid-js";
import { useCommander } from "./hooks";
import { CommanderInput } from "./CommanderInput";
import { CommanderEntries } from "./CommanderEntries";
import { TrackerView } from "./TrackerView";
import { TabBar } from "./TabBar";
import type { MdCommanderProps } from "./types";
import { loadElementSrc } from "../utils/path";
import { initializeCommands, loadCommandTemplatesFromCSV, getCommands, getCommandsLoading, getCommandsError } from "./stores";

customElement<MdCommanderProps>(
  "md-commander",
  { placeholder: "", class: "", height: "", commandTemplates: "" },
  (props, { element }) => {
    noShadowDOM();
    const { articlePath, rawSrc } = loadElementSrc(element as any);

    // 初始化命令
    const commands = initializeCommands(props.commands);
    const commander = useCommander(commands);

    // 使用 createResource 加载 CSV 模板
    const [templateData] = createResource(
      () => (rawSrc ? { path: rawSrc, articlePath } : null),
      async (paths) => {
        await loadCommandTemplatesFromCSV(paths.path, paths.articlePath);
        return getCommands();
      }
    );

    // 当模板加载完成后更新 commander 中的命令
    createResource(
      () => templateData(),
      (loadedCommands) => {
        if (loadedCommands) {
          commander.setCommands(loadedCommands);
        }
      }
    );

    const handleKeyDown = (e: KeyboardEvent) => {
      if (commander.showCompletions() && commander.completions().length > 0) {
        if (e.key === "ArrowDown") {
          e.preventDefault();
          commander.setSelectedCompletion(
            (prev) => (prev + 1) % commander.completions().length,
          );
          return;
        }
        if (e.key === "ArrowUp") {
          e.preventDefault();
          commander.setSelectedCompletion(
            (prev) => (prev - 1 + commander.completions().length) % commander.completions().length,
          );
          return;
        }
        if (e.key === "Tab") {
          e.preventDefault();
          commander.acceptCompletion();
          return;
        }
        if (e.key === "Escape") {
          commander.setShowCompletions(false);
          return;
        }
      }

      if (e.key === "ArrowUp" && !commander.showCompletions()) {
        e.preventDefault();
        commander.navigateHistory("up");
        return;
      }
      if (e.key === "ArrowDown" && !commander.showCompletions()) {
        e.preventDefault();
        commander.navigateHistory("down");
        return;
      }

      if (e.key === "Enter" && !e.shiftKey) {
        e.preventDefault();
        commander.handleCommand();
      }
    };

    const heightStyle = () => props.height || "400px";

    onMount(() => {
      const handleClickOutside = (e: MouseEvent) => {
        if (!element?.contains(e.target as Node)) {
          commander.setShowCompletions(false);
        }
      };
      document.addEventListener("click", handleClickOutside);
      onCleanup(() => document.removeEventListener("click", handleClickOutside));
    });

    return (
      <div
        class={`md-commander flex flex-col border border-gray-300 rounded-lg overflow-hidden ${props.class || ""}`}
        style={{ height: heightStyle() }}
      >
        <TabBar mode={commander.viewMode} onModeChange={commander.setViewMode} />

        <Show
          when={commander.viewMode() === "history"}
          fallback={
            <TrackerView
              items={commander.trackerItems}
              onEditAttribute={(index, attrName, attr) =>
                commander.updateTrackerAttributeByIndex(index, attrName, attr)
              }
              onClassesChange={(index, classes) =>
                commander.updateTrackerClassesByIndex(index, classes)
              }
              onRemoveClass={(index, className) =>
                commander.removeTrackerItemClassByIndex(index, className)
              }
              onMoveUp={(index) => commander.moveTrackerItemByIndex(index, "up")}
              onMoveDown={(index) => commander.moveTrackerItemByIndex(index, "down")}
              onRemove={(index) => commander.removeTrackerItemByIndex(index)}
            />
          }
        >
          <CommanderEntries
            entries={commander.entries}
            loading={getCommandsLoading()}
            error={getCommandsError()}
            onCommandClick={(cmd) => commander.setInputValue(cmd)}
          />
        </Show>

        <div class="relative border-t border-gray-300">
          <CommanderInput
            placeholder={props.placeholder}
            inputValue={commander.inputValue}
            onInput={(e) => {
              commander.setInputValue((e.target as HTMLInputElement).value);
              commander.updateCompletions();
            }}
            onKeyDown={handleKeyDown}
            onFocus={() => {
              commander.setIsFocused(true);
              commander.updateCompletions();
            }}
            onBlur={() => commander.setIsFocused(false)}
            onSubmit={commander.handleCommand}
            showCompletions={commander.showCompletions}
            completions={commander.completions}
            selectedCompletion={commander.selectedCompletion}
            onSelectCompletion={commander.setSelectedCompletion}
            onAcceptCompletion={commander.acceptCompletion}
          />
        </div>
      </div>
    );
  },
);
