import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
import { getModuleApiBase } from "../shared/url-helpers";

const styles = css`
	:host {
		background: var(--rs-bg-surface, #0f172a);
		color: var(--rs-text-primary, #e2e8f0);
		border-radius: 8px;
		box-shadow: var(--rs-shadow-md, 0 2px 12px rgba(0, 0, 0, 0.3));
		min-width: 360px;
		min-height: 320px;
		overflow: hidden;
	}

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

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

	.status-badge {
		padding: 2px 8px;
		border-radius: 10px;
		font-size: 10px;
		font-weight: 700;
		text-transform: uppercase;
	}
	.status-draft { background: #334155; color: #94a3b8; }
	.status-pending { background: #fbbf24; color: #1e293b; }
	.status-approved { background: #22c55e; color: white; }
	.status-sent { background: #22c55e; color: white; }
	.status-rejected { background: #ef4444; color: white; }

	.body {
		padding: 10px 12px;
		display: flex;
		flex-direction: column;
		gap: 6px;
		height: calc(100% - 36px);
		overflow-y: auto;
	}

	.field {
		display: flex;
		gap: 6px;
		font-size: 12px;
		align-items: baseline;
	}

	.field-label {
		color: #64748b;
		font-weight: 600;
		min-width: 50px;
		flex-shrink: 0;
	}

	.field-value {
		color: #cbd5e1;
		word-break: break-all;
	}

	.field-input {
		flex: 1;
		background: rgba(0,0,0,0.3);
		border: 1px solid #334155;
		border-radius: 4px;
		padding: 3px 6px;
		color: #e2e8f0;
		font-size: 12px;
		font-family: inherit;
		outline: none;
	}
	.field-input:focus { border-color: #6366f1; }

	.field-textarea {
		flex: 1;
		background: rgba(0,0,0,0.3);
		border: 1px solid #334155;
		border-radius: 4px;
		padding: 4px 6px;
		color: #e2e8f0;
		font-size: 12px;
		font-family: inherit;
		outline: none;
		resize: vertical;
		min-height: 48px;
		max-height: 120px;
	}
	.field-textarea:focus { border-color: #6366f1; }

	.divider {
		border: none;
		border-top: 1px solid #1e293b;
		margin: 4px 0;
	}

	.body-preview {
		font-size: 11px;
		color: #94a3b8;
		line-height: 1.4;
		max-height: 60px;
		overflow: hidden;
		padding: 6px;
		background: rgba(0,0,0,0.2);
		border-radius: 4px;
		border-left: 3px solid #334155;
	}

	/* Progress */
	.progress-section {
		margin-top: auto;
	}

	.progress-bar-wrap {
		display: flex;
		align-items: center;
		gap: 8px;
		margin-bottom: 6px;
	}

	.progress-bar {
		flex: 1;
		height: 6px;
		background: #1e293b;
		border-radius: 3px;
		overflow: hidden;
	}

	.progress-fill {
		height: 100%;
		border-radius: 3px;
		transition: width 0.3s;
	}
	.progress-fill.pending { background: linear-gradient(90deg, #fbbf24, #f59e0b); }
	.progress-fill.approved, .progress-fill.sent { background: linear-gradient(90deg, #22c55e, #16a34a); }

	.progress-text {
		font-size: 10px;
		color: #64748b;
		flex-shrink: 0;
	}

	.signer-row {
		display: flex;
		align-items: center;
		gap: 6px;
		font-size: 11px;
		padding: 2px 0;
	}

	.signer-dot {
		width: 14px;
		height: 14px;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 8px;
		color: white;
		flex-shrink: 0;
	}
	.signer-dot.signed { background: #22c55e; }
	.signer-dot.waiting { background: #334155; }

	.signer-name { flex: 1; }
	.signer-name.signed { color: #e2e8f0; }
	.signer-name.waiting { color: #64748b; }

	.signer-status { font-size: 10px; font-weight: 600; }
	.signer-status.signed { color: #4ade80; }
	.signer-status.waiting { color: #64748b; }

	/* Actions */
	.actions {
		display: flex;
		gap: 6px;
		margin-top: 6px;
		padding-top: 6px;
		border-top: 1px solid #1e293b;
	}

	.btn {
		padding: 4px 12px;
		border-radius: 4px;
		border: none;
		cursor: pointer;
		font-size: 11px;
		font-weight: 600;
		transition: opacity 0.15s;
	}
	.btn:hover { opacity: 0.85; }
	.btn-primary { background: #6366f1; color: white; }
	.btn-success { background: #22c55e; color: white; }
	.btn-danger { background: #ef4444; color: white; }
	.btn-secondary { background: #334155; color: #94a3b8; }
`;

export class FolkMultisigEmail extends FolkShape {
	static tagName = "folk-multisig-email";

	// Shape data
	mailboxSlug = "";
	toAddresses: string[] = [];
	ccAddresses: string[] = [];
	subject = "";
	bodyText = "";
	bodyHtml = "";
	replyToThreadId: string | null = null;
	replyType: 'new' | 'reply' | 'forward' = 'new';
	approvalType: 'email' | 'newsletter' = 'email';
	listmonkCampaignId: number | null = null;
	approvalId: string | null = null;
	status: 'draft' | 'pending' | 'approved' | 'sent' | 'rejected' = 'draft';
	requiredSignatures = 2;
	signatures: Array<{ id: string; signerId: string; vote: string; signedAt: string }> = [];

	private _pollInterval: ReturnType<typeof setInterval> | null = null;

	static override fromData(data: Record<string, any>): FolkMultisigEmail {
		const shape = FolkShape.fromData(data) as FolkMultisigEmail;
		if (data.mailboxSlug !== undefined) shape.mailboxSlug = data.mailboxSlug;
		if (Array.isArray(data.toAddresses)) shape.toAddresses = data.toAddresses;
		if (Array.isArray(data.ccAddresses)) shape.ccAddresses = data.ccAddresses;
		if (data.subject !== undefined) shape.subject = data.subject;
		if (data.bodyText !== undefined) shape.bodyText = data.bodyText;
		if (data.bodyHtml !== undefined) shape.bodyHtml = data.bodyHtml;
		if (data.replyToThreadId !== undefined) shape.replyToThreadId = data.replyToThreadId;
		if (data.replyType !== undefined) shape.replyType = data.replyType;
		if (data.approvalType !== undefined) shape.approvalType = data.approvalType;
		if (data.listmonkCampaignId !== undefined) shape.listmonkCampaignId = data.listmonkCampaignId;
		if (data.approvalId !== undefined) shape.approvalId = data.approvalId;
		if (data.status !== undefined) shape.status = data.status;
		if (typeof data.requiredSignatures === "number") shape.requiredSignatures = data.requiredSignatures;
		if (Array.isArray(data.signatures)) shape.signatures = data.signatures;
		return shape;
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (data.mailboxSlug !== undefined && data.mailboxSlug !== this.mailboxSlug) this.mailboxSlug = data.mailboxSlug;
		if (Array.isArray(data.toAddresses) && JSON.stringify(data.toAddresses) !== JSON.stringify(this.toAddresses)) this.toAddresses = data.toAddresses;
		if (Array.isArray(data.ccAddresses) && JSON.stringify(data.ccAddresses) !== JSON.stringify(this.ccAddresses)) this.ccAddresses = data.ccAddresses;
		if (data.subject !== undefined && data.subject !== this.subject) this.subject = data.subject;
		if (data.bodyText !== undefined && data.bodyText !== this.bodyText) this.bodyText = data.bodyText;
		if (data.bodyHtml !== undefined && data.bodyHtml !== this.bodyHtml) this.bodyHtml = data.bodyHtml;
		if (data.replyToThreadId !== undefined && data.replyToThreadId !== this.replyToThreadId) this.replyToThreadId = data.replyToThreadId;
		if (data.replyType !== undefined && data.replyType !== this.replyType) this.replyType = data.replyType;
		if (data.approvalType !== undefined && data.approvalType !== this.approvalType) this.approvalType = data.approvalType;
		if (data.listmonkCampaignId !== undefined && data.listmonkCampaignId !== this.listmonkCampaignId) this.listmonkCampaignId = data.listmonkCampaignId;
		if (data.approvalId !== undefined && data.approvalId !== this.approvalId) this.approvalId = data.approvalId;
		if (data.status !== undefined && data.status !== this.status) this.status = data.status;
		if (typeof data.requiredSignatures === "number" && data.requiredSignatures !== this.requiredSignatures) this.requiredSignatures = data.requiredSignatures;
		if (Array.isArray(data.signatures) && JSON.stringify(data.signatures) !== JSON.stringify(this.signatures)) this.signatures = data.signatures;
	}

	static get observedAttributes() {
		return [...super.observedAttributes, "mailbox-slug", "subject", "status", "approval-id"];
	}

	attributeChangedCallback(name: string, oldValue: string, newValue: string) {
		super.attributeChangedCallback(name, oldValue, newValue);
		switch (name) {
			case "mailbox-slug": this.mailboxSlug = newValue || ""; break;
			case "subject": this.subject = newValue || ""; break;
			case "status": this.status = (newValue || "draft") as any; break;
			case "approval-id": this.approvalId = newValue || null; break;
		}
	}

	connectedCallback() {
		super.connectedCallback();
		this.shadowRoot!.adoptedStyleSheets = [...this.shadowRoot!.adoptedStyleSheets, styles];
		this.renderContent();
		if (this.status === 'pending' && this.approvalId) {
			this.startPolling();
		}
	}

	disconnectedCallback() {
		super.disconnectedCallback();
		this.stopPolling();
	}

	private getApiBase(): string {
		return getModuleApiBase("rinbox");
	}

	private getAuthHeaders(): Record<string, string> {
		const headers: Record<string, string> = { "Content-Type": "application/json" };
		const token = localStorage.getItem("encryptid-token");
		if (token) headers["Authorization"] = `Bearer ${token}`;
		return headers;
	}

	private startPolling() {
		this.stopPolling();
		this._pollInterval = setInterval(() => this.pollApproval(), 5000);
	}

	private stopPolling() {
		if (this._pollInterval) {
			clearInterval(this._pollInterval);
			this._pollInterval = null;
		}
	}

	private async pollApproval() {
		if (!this.approvalId) return;
		try {
			const resp = await fetch(`${this.getApiBase()}/api/approvals/${this.approvalId}`, {
				headers: this.getAuthHeaders(),
			});
			if (!resp.ok) return;
			const data = await resp.json();
			const newStatus = data.status?.toLowerCase();
			if (newStatus && newStatus !== this.status) {
				this.status = newStatus;
				this.signatures = data.signatures || [];
				this.renderContent();
				this.dispatchEvent(new CustomEvent("content-change", { bubbles: true }));
				if (newStatus !== 'pending') this.stopPolling();
			} else {
				// Update signature count even if status didn't change
				if (data.signatures) {
					this.signatures = data.signatures;
					this.renderContent();
				}
			}
		} catch { /* ignore polling errors */ }
	}

	private renderContent() {
		const sr = this.shadowRoot;
		if (!sr) return;

		const isDraft = this.status === 'draft';
		const sigCount = this.signatures.filter(s => s.vote === 'APPROVE').length;
		const pct = this.requiredSignatures > 0 ? Math.min(100, Math.round((sigCount / this.requiredSignatures) * 100)) : 0;

		let contentEl = sr.querySelector(".msig-content") as HTMLDivElement;
		if (!contentEl) {
			contentEl = document.createElement("div");
			contentEl.className = "msig-content";
			contentEl.style.cssText = "display:flex;flex-direction:column;height:100%;";
			sr.appendChild(contentEl);
		}

		if (isDraft) {
			contentEl.innerHTML = html`
				<div class="header">
					<div class="header-title">&#9993; Multi-Sig Email</div>
					<span class="status-badge status-draft">Draft</span>
				</div>
				<div class="body">
					<div class="field">
						<span class="field-label">From:</span>
						<span class="field-value" style="color:#6366f1">${this.mailboxSlug || "team"}@rspace.online</span>
					</div>
					<div class="field">
						<span class="field-label">To:</span>
						<input class="field-input" data-field="to" value="${this.toAddresses.join(', ')}" placeholder="recipient@example.com" />
					</div>
					<div class="field">
						<span class="field-label">Subject:</span>
						<input class="field-input" data-field="subject" value="${this.escapeAttr(this.subject)}" placeholder="Email subject" />
					</div>
					<hr class="divider" />
					<textarea class="field-textarea" data-field="body" placeholder="Write your email...">${this.escapeHtml(this.bodyText)}</textarea>
					<div class="actions">
						<button class="btn btn-primary" data-action="submit">Submit for Approval</button>
					</div>
				</div>
			`;
		} else {
			const isNewsletter = this.approvalType === 'newsletter';
			const snippet = this.bodyText.length > 120 ? this.bodyText.slice(0, 120) + '...' : this.bodyText;
			const headerBg = this.status === 'sent' || this.status === 'approved' ? '#16a34a' : this.status === 'rejected' ? '#dc2626' : isNewsletter ? '#059669' : '#6366f1';
			const headerTitle = isNewsletter ? '&#128231; Newsletter Approval' : '&#9993; Multi-Sig Email';
			contentEl.innerHTML = html`
				<div class="header" style="background:${headerBg}">
					<div class="header-title">${headerTitle}</div>
					<span class="status-badge status-${this.status}">${this.status}</span>
				</div>
				<div class="body">
					<div class="field">
						<span class="field-label">From:</span>
						<span class="field-value" style="color:#6366f1">${this.mailboxSlug || "team"}@rspace.online</span>
					</div>
					${isNewsletter ? html`
					<div class="field">
						<span class="field-label">Type:</span>
						<span class="field-value">Newsletter Campaign</span>
					</div>
					${this.listmonkCampaignId ? html`
					<div class="field">
						<span class="field-label">Campaign:</span>
						<span class="field-value" style="font-weight:600">#${this.listmonkCampaignId}</span>
					</div>` : ''}
					` : html`
					<div class="field">
						<span class="field-label">To:</span>
						<span class="field-value">${this.toAddresses.join(', ') || '(none)'}</span>
					</div>`}
					<div class="field">
						<span class="field-label">Subject:</span>
						<span class="field-value" style="font-weight:600">${this.subject || '(no subject)'}</span>
					</div>
					<hr class="divider" />
					<div class="body-preview">${this.escapeHtml(snippet)}</div>
					<div class="progress-section">
						<div class="progress-bar-wrap">
							<div class="progress-bar">
								<div class="progress-fill ${this.status}" style="width:${pct}%"></div>
							</div>
							<span class="progress-text">${sigCount}/${this.requiredSignatures} signatures</span>
						</div>
						${this.signatures.map(s => html`
							<div class="signer-row">
								<div class="signer-dot ${s.vote === 'APPROVE' ? 'signed' : 'waiting'}">${s.vote === 'APPROVE' ? '&#10003;' : ''}</div>
								<span class="signer-name ${s.vote === 'APPROVE' ? 'signed' : 'waiting'}">${s.signerId?.slice(0, 12) || 'Unknown'}...</span>
								<span class="signer-status ${s.vote === 'APPROVE' ? 'signed' : 'waiting'}">${s.vote === 'APPROVE' ? 'Signed' : 'Awaiting'}</span>
							</div>
						`).join('')}
					</div>
					${this.status === 'pending' ? html`
						<div class="actions">
							<button class="btn btn-success" data-action="approve">&#10003; Approve</button>
							<button class="btn btn-danger" data-action="reject">&#10007; Reject</button>
						</div>
					` : ''}
					${this.status === 'draft' ? html`
						<div class="actions">
							<button class="btn btn-secondary" data-action="edit">Edit</button>
							<button class="btn btn-primary" data-action="submit">Submit</button>
						</div>
					` : ''}
				</div>
			`;
		}

		this.bindShapeEvents(contentEl);
	}

	private escapeHtml(s: string): string {
		return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
	}

	private escapeAttr(s: string): string {
		return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
	}

	private bindShapeEvents(root: HTMLElement) {
		// Draft field changes
		root.querySelectorAll("[data-field]").forEach(el => {
			el.addEventListener("input", () => {
				const field = (el as HTMLElement).dataset.field;
				const value = (el as HTMLInputElement | HTMLTextAreaElement).value;
				switch (field) {
					case 'to':
						this.toAddresses = value.split(',').map(s => s.trim()).filter(Boolean);
						break;
					case 'subject':
						this.subject = value;
						break;
					case 'body':
						this.bodyText = value;
						break;
				}
				this.dispatchEvent(new CustomEvent("content-change", { bubbles: true }));
			});
		});

		// Submit
		root.querySelector("[data-action='submit']")?.addEventListener("click", async () => {
			if (!this.subject || (this.approvalType !== 'newsletter' && this.toAddresses.length === 0)) {
				alert("Please fill Subject" + (this.approvalType !== 'newsletter' ? " and To fields." : "."));
				return;
			}
			try {
				const resp = await fetch(`${this.getApiBase()}/api/approvals`, {
					method: "POST",
					headers: this.getAuthHeaders(),
					body: JSON.stringify({
						mailbox_slug: this.mailboxSlug || undefined,
						subject: this.subject,
						body_text: this.bodyText,
						to_addresses: this.toAddresses,
						cc_addresses: this.ccAddresses,
						reply_type: this.replyType,
						thread_id: this.replyToThreadId,
					}),
				});
				if (resp.ok) {
					const data = await resp.json();
					this.approvalId = data.id;
					this.status = 'pending';
					this.requiredSignatures = data.required_signatures || 2;
					this.renderContent();
					this.dispatchEvent(new CustomEvent("content-change", { bubbles: true }));
					this.startPolling();
				}
			} catch (e) {
				console.error("[MultiSigEmail] Submit error:", e);
			}
		});

		// Approve
		root.querySelector("[data-action='approve']")?.addEventListener("click", async () => {
			if (!this.approvalId) return;
			try {
				const resp = await fetch(`${this.getApiBase()}/api/approvals/${this.approvalId}/sign`, {
					method: "POST",
					headers: this.getAuthHeaders(),
					body: JSON.stringify({ vote: "APPROVE" }),
				});
				if (resp.ok) {
					const data = await resp.json();
					if (data.status) {
						this.status = data.status.toLowerCase();
						if (this.status !== 'pending') this.stopPolling();
					}
					this.renderContent();
					this.dispatchEvent(new CustomEvent("content-change", { bubbles: true }));
				}
			} catch (e) {
				console.error("[MultiSigEmail] Approve error:", e);
			}
		});

		// Reject
		root.querySelector("[data-action='reject']")?.addEventListener("click", async () => {
			if (!this.approvalId) return;
			try {
				const resp = await fetch(`${this.getApiBase()}/api/approvals/${this.approvalId}/sign`, {
					method: "POST",
					headers: this.getAuthHeaders(),
					body: JSON.stringify({ vote: "REJECT" }),
				});
				if (resp.ok) {
					const data = await resp.json();
					if (data.status) this.status = data.status.toLowerCase();
					this.stopPolling();
					this.renderContent();
					this.dispatchEvent(new CustomEvent("content-change", { bubbles: true }));
				}
			} catch (e) {
				console.error("[MultiSigEmail] Reject error:", e);
			}
		});
	}
}

customElements.define(FolkMultisigEmail.tagName, FolkMultisigEmail);
