/**
 * folk-gov-binary — Yes/No Signoff Gate
 *
 * A simple binary governance gate. An optional assignee can be specified
 * (who must sign off). When checked, emits { satisfied: true } on gate-out.
 */

import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
import type { PortDescriptor } from "./data-types";

const HEADER_COLOR = "#7c3aed";

const styles = css`
	:host {
		background: var(--rs-bg-surface, #1e293b);
		border-radius: 10px;
		box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
		min-width: 200px;
		min-height: 80px;
		overflow: hidden;
	}

	.header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 8px 12px;
		background: ${HEADER_COLOR};
		color: white;
		font-size: 12px;
		font-weight: 600;
		cursor: move;
		border-radius: 10px 10px 0 0;
	}

	.header-title {
		display: flex;
		align-items: center;
		gap: 6px;
	}

	.header-actions button {
		background: transparent;
		border: none;
		color: white;
		cursor: pointer;
		padding: 2px 6px;
		border-radius: 4px;
		font-size: 14px;
	}

	.header-actions button:hover {
		background: rgba(255, 255, 255, 0.2);
	}

	.body {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		padding: 16px;
		gap: 8px;
	}

	.title-input {
		background: transparent;
		border: none;
		color: var(--rs-text-primary, #e2e8f0);
		font-size: 13px;
		font-weight: 600;
		text-align: center;
		width: 100%;
		outline: none;
	}

	.title-input::placeholder {
		color: var(--rs-text-muted, #64748b);
	}

	.assignee-row {
		display: flex;
		align-items: center;
		gap: 6px;
		font-size: 11px;
		color: var(--rs-text-muted, #94a3b8);
	}

	.assignee-input {
		background: rgba(255, 255, 255, 0.06);
		border: 1px solid rgba(255, 255, 255, 0.1);
		border-radius: 4px;
		color: var(--rs-text-primary, #e2e8f0);
		font-size: 11px;
		padding: 2px 6px;
		width: 100px;
		outline: none;
	}

	.check-area {
		display: flex;
		align-items: center;
		justify-content: center;
		margin-top: 4px;
	}

	.gate-checkbox {
		width: 36px;
		height: 36px;
		appearance: none;
		-webkit-appearance: none;
		border: 3px solid rgba(255, 255, 255, 0.3);
		border-radius: 8px;
		background: transparent;
		cursor: pointer;
		position: relative;
		transition: all 0.2s;
	}

	.gate-checkbox:checked {
		background: #22c55e;
		border-color: #22c55e;
		box-shadow: 0 0 12px rgba(34, 197, 94, 0.4);
	}

	.gate-checkbox:checked::after {
		content: "✓";
		position: absolute;
		inset: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		color: white;
		font-size: 20px;
		font-weight: 700;
	}

	.gate-checkbox:not(:checked) {
		box-shadow: 0 0 8px rgba(245, 158, 11, 0.3);
		border-color: #f59e0b;
	}

	.status-label {
		font-size: 10px;
		font-weight: 500;
		text-transform: uppercase;
		letter-spacing: 0.5px;
	}

	.status-label.satisfied {
		color: #22c55e;
	}

	.status-label.waiting {
		color: #f59e0b;
	}
`;

declare global {
	interface HTMLElementTagNameMap {
		"folk-gov-binary": FolkGovBinary;
	}
}

export class FolkGovBinary extends FolkShape {
	static override tagName = "folk-gov-binary";

	static override portDescriptors: PortDescriptor[] = [
		{ name: "gate-out", type: "json", direction: "output" },
	];

	static {
		const sheet = new CSSStyleSheet();
		const parentRules = Array.from(FolkShape.styles.cssRules).map(r => r.cssText).join("\n");
		const childRules = Array.from(styles.cssRules).map(r => r.cssText).join("\n");
		sheet.replaceSync(`${parentRules}\n${childRules}`);
		this.styles = sheet;
	}

	#title = "Signoff Required";
	#assignee = "";
	#satisfied = false;
	#signedBy = "";
	#timestamp = 0;

	// DOM refs
	#titleEl!: HTMLInputElement;
	#assigneeEl!: HTMLInputElement;
	#checkboxEl!: HTMLInputElement;
	#statusEl!: HTMLElement;

	get title() { return this.#title; }
	set title(v: string) {
		this.#title = v;
		if (this.#titleEl) this.#titleEl.value = v;
	}

	get assignee() { return this.#assignee; }
	set assignee(v: string) {
		this.#assignee = v;
		if (this.#assigneeEl) this.#assigneeEl.value = v;
	}

	get satisfied() { return this.#satisfied; }
	set satisfied(v: boolean) {
		this.#satisfied = v;
		if (this.#checkboxEl) this.#checkboxEl.checked = v;
		this.#updateVisuals();
		this.#emitPort();
	}

	get signedBy() { return this.#signedBy; }
	set signedBy(v: string) { this.#signedBy = v; }

	get timestamp() { return this.#timestamp; }
	set timestamp(v: number) { this.#timestamp = v; }

	override createRenderRoot() {
		const root = super.createRenderRoot();
		this.initPorts();

		const wrapper = document.createElement("div");
		wrapper.style.cssText = "width:100%;height:100%;display:flex;flex-direction:column;";
		wrapper.innerHTML = html`
			<div class="header" data-drag>
				<span class="header-title">⚖️ Binary Gate</span>
				<span class="header-actions">
					<button class="close-btn">&times;</button>
				</span>
			</div>
			<div class="body">
				<input class="title-input" type="text" placeholder="Gate title..." />
				<div class="assignee-row">
					<span>Assignee:</span>
					<input class="assignee-input" type="text" placeholder="anyone" />
				</div>
				<div class="check-area">
					<input class="gate-checkbox" type="checkbox" />
				</div>
				<span class="status-label waiting">WAITING</span>
			</div>
		`;

		const slot = root.querySelector("slot");
		const container = slot?.parentElement as HTMLElement;
		if (container) container.replaceWith(wrapper);

		// Cache refs
		this.#titleEl = wrapper.querySelector(".title-input") as HTMLInputElement;
		this.#assigneeEl = wrapper.querySelector(".assignee-input") as HTMLInputElement;
		this.#checkboxEl = wrapper.querySelector(".gate-checkbox") as HTMLInputElement;
		this.#statusEl = wrapper.querySelector(".status-label") as HTMLElement;

		// Set initial values
		this.#titleEl.value = this.#title;
		this.#assigneeEl.value = this.#assignee;
		this.#checkboxEl.checked = this.#satisfied;
		this.#updateVisuals();

		// Wire events
		this.#titleEl.addEventListener("input", (e) => {
			e.stopPropagation();
			this.#title = this.#titleEl.value;
			this.dispatchEvent(new CustomEvent("content-change"));
		});

		this.#assigneeEl.addEventListener("input", (e) => {
			e.stopPropagation();
			this.#assignee = this.#assigneeEl.value;
			this.dispatchEvent(new CustomEvent("content-change"));
		});

		this.#checkboxEl.addEventListener("change", (e) => {
			e.stopPropagation();
			this.#satisfied = this.#checkboxEl.checked;
			this.#signedBy = this.#satisfied ? (this.#assignee || "anonymous") : "";
			this.#timestamp = this.#satisfied ? Date.now() : 0;
			this.#updateVisuals();
			this.#emitPort();
			this.dispatchEvent(new CustomEvent("content-change"));
		});

		wrapper.querySelector(".close-btn")!.addEventListener("click", (e) => {
			e.stopPropagation();
			this.dispatchEvent(new CustomEvent("close"));
		});

		// Prevent drag on inputs
		this.#titleEl.addEventListener("pointerdown", (e) => e.stopPropagation());
		this.#assigneeEl.addEventListener("pointerdown", (e) => e.stopPropagation());
		this.#checkboxEl.addEventListener("pointerdown", (e) => e.stopPropagation());

		return root;
	}

	#updateVisuals() {
		if (!this.#statusEl) return;
		if (this.#satisfied) {
			this.#statusEl.textContent = "SATISFIED";
			this.#statusEl.className = "status-label satisfied";
		} else {
			this.#statusEl.textContent = "WAITING";
			this.#statusEl.className = "status-label waiting";
		}
	}

	#emitPort() {
		this.setPortValue("gate-out", {
			satisfied: this.#satisfied,
			signedBy: this.#signedBy,
			timestamp: this.#timestamp,
		});
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-gov-binary",
			title: this.#title,
			assignee: this.#assignee,
			satisfied: this.#satisfied,
			signedBy: this.#signedBy,
			timestamp: this.#timestamp,
		};
	}

	static override fromData(data: Record<string, any>): FolkGovBinary {
		const shape = FolkShape.fromData.call(this, data) as FolkGovBinary;
		if (data.title !== undefined) shape.title = data.title;
		if (data.assignee !== undefined) shape.assignee = data.assignee;
		if (data.satisfied !== undefined) shape.satisfied = data.satisfied;
		if (data.signedBy !== undefined) shape.signedBy = data.signedBy;
		if (data.timestamp !== undefined) shape.timestamp = data.timestamp;
		return shape;
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (data.title !== undefined && data.title !== this.#title) this.title = data.title;
		if (data.assignee !== undefined && data.assignee !== this.#assignee) this.assignee = data.assignee;
		if (data.satisfied !== undefined && data.satisfied !== this.#satisfied) this.satisfied = data.satisfied;
		if (data.signedBy !== undefined && data.signedBy !== this.#signedBy) this.signedBy = data.signedBy;
		if (data.timestamp !== undefined && data.timestamp !== this.#timestamp) this.timestamp = data.timestamp;
	}
}
