import { html, LitElement } from "lit";
import { customElement, state } from "lit/decorators.js";

export interface Command {
	id: string;
	label: string;
	description?: string;
	icon?: string;
	shortcut?: string;
	action: () => void;
	keywords?: string[];
}

@customElement("command-palette")
export class CommandPalette extends LitElement {
	@state() private open = false;
	@state() private query = "";
	@state() private selectedIndex = 0;

	private commands: Command[] = [];

	protected override createRenderRoot() {
		return this;
	}

	setCommands(commands: Command[]) {
		this.commands = commands;
	}

	show() {
		this.open = true;
		this.query = "";
		this.selectedIndex = 0;
		this.requestUpdate();
		requestAnimationFrame(() => {
			const input = this.querySelector("input") as HTMLInputElement;
			if (input) input.focus();
		});
	}

	hide() {
		this.open = false;
		this.requestUpdate();
	}

	get filteredCommands(): Command[] {
		if (!this.query) return this.commands;
		const q = this.query.toLowerCase();
		return this.commands.filter(
			(c) =>
				c.label.toLowerCase().includes(q) ||
				c.description?.toLowerCase().includes(q) ||
				c.keywords?.some((k) => k.toLowerCase().includes(q)),
		);
	}

	private handleKeyDown(e: KeyboardEvent) {
		const cmds = this.filteredCommands;
		if (e.key === "ArrowDown") {
			e.preventDefault();
			this.selectedIndex = Math.min(this.selectedIndex + 1, cmds.length - 1);
		} else if (e.key === "ArrowUp") {
			e.preventDefault();
			this.selectedIndex = Math.max(this.selectedIndex - 1, 0);
		} else if (e.key === "Enter") {
			e.preventDefault();
			if (cmds[this.selectedIndex]) {
				cmds[this.selectedIndex].action();
				this.hide();
			}
		} else if (e.key === "Escape") {
			this.hide();
		}
	}

	override render() {
		if (!this.open) return html``;
		const cmds = this.filteredCommands;

		return html`
      <div class="fixed inset-0 z-50 flex items-start justify-center pt-20" @click=${(e: Event) => {
			if (e.target === e.currentTarget) this.hide();
		}}>
        <div class="w-full max-w-xl bg-popover border border-border rounded-xl shadow-2xl overflow-hidden">
          <div class="flex items-center gap-3 px-4 py-3 border-b border-border">
            <span class="text-muted-foreground text-sm">&#x2318;</span>
            <input
              type="text"
              placeholder="Type a command..."
              class="flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
              .value=${this.query}
              @input=${(e: Event) => {
						this.query = (e.target as HTMLInputElement).value;
						this.selectedIndex = 0;
					}}
              @keydown=${this.handleKeyDown}
            />
            <kbd class="text-xs text-muted-foreground border border-border rounded px-1.5 py-0.5">ESC</kbd>
          </div>
          <div class="max-h-80 overflow-y-auto py-1">
            ${cmds.length === 0 ? html`<div class="px-4 py-6 text-center text-sm text-muted-foreground">No commands found</div>` : ""}
            ${cmds.map(
					(cmd, i) => html`
              <button
                class="w-full flex items-center justify-between px-4 py-2.5 text-sm hover:bg-secondary transition-colors text-left ${
							i === this.selectedIndex ? "bg-secondary" : ""
						}"
                @click=${() => {
							cmd.action();
							this.hide();
						}}
                @mouseover=${() => {
							this.selectedIndex = i;
						}}
              >
                <div class="flex flex-col gap-0.5">
                  <span class="font-medium">${cmd.label}</span>
                  ${cmd.description ? html`<span class="text-xs text-muted-foreground">${cmd.description}</span>` : ""}
                </div>
                ${cmd.shortcut ? html`<kbd class="text-xs text-muted-foreground border border-border rounded px-1.5 py-0.5 shrink-0">${cmd.shortcut}</kbd>` : ""}
              </button>
            `,
				)}
          </div>
          <div class="px-4 py-2 border-t border-border text-xs text-muted-foreground flex items-center gap-4">
            <span>&#x2191;&#x2193; Navigate</span>
            <span>&#x21B5; Select</span>
            <span>ESC Close</span>
          </div>
        </div>
      </div>
    `;
	}
}
