import { exportInvoicePdfFromSlug } from '../../woocommerce/invoice/exportInvoicePdf';
import { getConfig, parseOrderId } from './config';
import { setSpinner, replaceButtonWithFilename, showError } from './ui';
import { fetchInvoiceContext, downloadBlob, downloadExistingInvoice, uploadInvoicePdf, getCustomerDesignEndpoint } from './api';

function dbg(...args: any[]): void {
	const cfg = getConfig();
	if (!cfg.debug) return;
	// eslint-disable-next-line no-console
	console.log('[pdfdraft-pdf-invoices-for-woocommerce:invoice-download]', ...args);
}

function getButton(el: HTMLElement): HTMLElement | null {
	return el.closest('.PDFDraft-Invoice-Download-Button') as HTMLElement | null;
}


function getWooInvoiceActionLink(el: HTMLElement): HTMLAnchorElement | null {
	const a = el.closest('a.order-actions-button.pdfdraft_invoice') as HTMLAnchorElement | null;
	if (!a) return null;
	const href = a.getAttribute('href') ?? '';
	return href.includes('#pdfdraft-invoice-') ? a : null;
}

function parseOrderIdFromInvoiceFragment(href: string): number | null {
	const m = href.match(/#pdfdraft-invoice-(\d+)/);
	const id = m?.[1];
	if (!id) return null;
	return parseInt(id, 10);
}

function setLoadingState(button: HTMLElement, show: boolean): void {
	if (button.classList.contains('PDFDraft-Invoice-Download-Button')) {
		setSpinner(button, show);
		return;
	}
	button.setAttribute('aria-busy', show ? 'true' : 'false');
	button.style.pointerEvents = show ? 'none' : '';
	button.style.opacity = show ? '0.65' : '';
}

export function initDownloadHandler(): void {
	document.addEventListener('click', (e) => {
		const target = e.target as HTMLElement;
		const pdfdraftButton = getButton(target);
		const wooLink = getWooInvoiceActionLink(target);

		const button = pdfdraftButton ?? wooLink;
		if (!button) return;
		e.preventDefault();

		let orderId: number | null = null;
		let context = '';

		if (pdfdraftButton) {
			orderId = parseOrderId(pdfdraftButton.getAttribute('data-order-id') ?? undefined);
			context = pdfdraftButton.getAttribute('data-context') ?? '';
		} else if (wooLink) {
			orderId = parseOrderIdFromInvoiceFragment(wooLink.getAttribute('href') ?? '');
			context = 'my-account';
		}

		if (!orderId) {
			showError(button, getConfig().i18n?.errorDownloadFailed);
			return;
		}

		const nonce = getConfig().nonce ?? '';
		if (!nonce) {
			showError(button, getConfig().i18n?.errorDownloadFailed);
			return;
		}

		dbg('click', { orderId, context, hasPdfdraftButton: Boolean(pdfdraftButton), hasWooLink: Boolean(wooLink) });
		setLoadingState(button, true);

		fetchInvoiceContext(orderId, nonce, context)
			.then(async (ctx) => {
				dbg('context', { orderId, isGenerated: ctx.isGenerated, designSlug: ctx.designSlug });
				if (ctx.isGenerated) {
					dbg('path', 'downloadExistingInvoice');
					await downloadExistingInvoice(orderId, nonce, context);
					return;
				}

				// For customer-facing pages, use the customer design endpoint.
				const designEndpoint = context === 'my-account'
					? getCustomerDesignEndpoint(orderId)
					: undefined;

				dbg('path', 'exportInvoicePdfFromSlug', { designEndpoint: Boolean(designEndpoint) });
				const { blob, filename } = await exportInvoicePdfFromSlug(
					ctx.designSlug,
					ctx.mergeTags,
					orderId,
					nonce,
					designEndpoint,
				);

				downloadBlob(blob, filename);

				uploadInvoicePdf(orderId, blob, nonce, context)
					.then(() => {
						dbg('uploadInvoicePdf', 'success');
						if (button.closest('.PDFDraft-Invoice-Wrap')) {
							replaceButtonWithFilename(button, filename);
						}
					})
					.catch(() => {
						dbg('uploadInvoicePdf', 'failed');
						// Upload failed silently — download already succeeded.
					});
			})
			.catch((err) => {
				dbg('error', 'fetchInvoiceContext failed', {
					message: (err as any)?.message,
					status: (err as any)?.status,
					body: (err as any)?.body,
				});
				showError(button, getConfig().i18n?.errorDownloadFailed);
			})
			.finally(() => {
				setLoadingState(button, false);
			});
	});
}
