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

@customElement("jae-browser-panel")
export class JaeBrowserPanel extends LitElement {
	@state() private url = "";
	@state() private inputUrl = "";
	@state() private screenshot = "";
	@state() private loading = false;
	@state() private connected = false;
	@state() private error = "";

	private ws: WebSocket | null = null;
	private imgEl: HTMLImageElement | null = null;

	createRenderRoot() {
		return this;
	}

	override connectedCallback() {
		super.connectedCallback();
		this.style.display = "flex";
		this.style.flexDirection = "column";
		this.style.height = "100%";
		this.style.minHeight = "0";
		this.connect();
	}

	override disconnectedCallback() {
		super.disconnectedCallback();
		this.ws?.close();
	}

	connect() {
		this.ws = new WebSocket("ws://localhost:7700/ws/browser");
		this.ws.onopen = () => {
			this.connected = true;
			this.requestUpdate();
		};
		this.ws.onclose = () => {
			this.connected = false;
			this.requestUpdate();
		};
		this.ws.onerror = () => {
			this.connected = false;
			this.error = "Browser server not running.";
			this.requestUpdate();
		};
		this.ws.onmessage = (e) => {
			const m = JSON.parse(e.data);
			if (m.type === "screenshot") {
				this.loading = false;
				this.screenshot = `data:image/jpeg;base64,${m.data}`;
				this.url = m.url;
				this.inputUrl = m.url;
				this.error = "";
				this.requestUpdate();
			}
			if (m.type === "loading") {
				this.loading = true;
				this.requestUpdate();
			}
			if (m.type === "error") {
				this.loading = false;
				this.error = m.msg;
				this.requestUpdate();
			}
		};
	}

	navigate(url?: string) {
		const target = url || this.inputUrl;
		if (!target) return;
		this.ws?.send(JSON.stringify({ type: "navigate", url: target }));
		this.loading = true;
		this.requestUpdate();
	}

	private handleImgClick(e: MouseEvent) {
		const img = e.currentTarget as HTMLImageElement;
		const rect = img.getBoundingClientRect();
		const scaleX = 1280 / rect.width;
		const scaleY = 800 / rect.height;
		const x = (e.clientX - rect.left) * scaleX;
		const y = (e.clientY - rect.top) * scaleY;
		this.ws?.send(JSON.stringify({ type: "click", x, y }));
		this.loading = true;
		this.requestUpdate();
	}

	private handleScroll(e: WheelEvent) {
		e.preventDefault();
		this.ws?.send(JSON.stringify({ type: "scroll", dy: e.deltaY }));
	}

	override render() {
		return html`
      <div class="flex items-center gap-1 px-2 py-1 border-b border-border shrink-0 bg-muted/30" style="height:40px">
        <button class="p-1 rounded hover:bg-secondary" title="Back" @click=${() => this.ws?.send(JSON.stringify({ type: "back" }))}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
        </button>
        <button class="p-1 rounded hover:bg-secondary" title="Forward" @click=${() => this.ws?.send(JSON.stringify({ type: "fwd" }))}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
        </button>
        <button class="p-1 rounded hover:bg-secondary" title="Reload" @click=${() => this.ws?.send(JSON.stringify({ type: "reload" }))}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>
        </button>
        <input
          class="flex-1 text-xs border border-border rounded px-2 py-1 bg-background text-foreground outline-none focus:ring-1 focus:ring-ring"
          type="text"
          .value=${this.inputUrl}
          @input=${(e: Event) => {
					this.inputUrl = (e.target as HTMLInputElement).value;
				}}
          @keydown=${(e: KeyboardEvent) => {
					if (e.key === "Enter") this.navigate();
				}}
          placeholder="Enter URL and press Enter..."
        />
        <div class="w-2 h-2 rounded-full ml-1 ${this.connected ? "bg-green-500" : "bg-red-500"}" title="${this.connected ? "connected" : "disconnected"}"></div>
      </div>
      <div class="flex-1 overflow-auto min-h-0 relative bg-white">
        ${
				this.loading
					? html`
          <div class="absolute inset-0 flex items-center justify-center bg-background/80 z-10">
            <div class="text-sm text-muted-foreground">Loading...</div>
          </div>
        `
					: html``
			}
        ${
				this.error
					? html`
          <div class="p-4 text-sm text-red-500">${this.error}</div>
        `
					: html``
			}
        ${
				this.screenshot
					? html`
          <img
            src=${this.screenshot}
            class="w-full cursor-crosshair"
            style="display:block"
            alt="browser"
            @click=${this.handleImgClick}
            @wheel=${this.handleScroll}
          />
        `
					: !this.error
						? html`
          <div class="flex flex-col items-center justify-center h-full text-muted-foreground gap-2">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
            <p class="text-sm">Enter a URL above to browse</p>
          </div>
        `
						: html``
			}
      </div>
    `;
	}
}
