import { getConfig } from './config';

function getBaseUrl(): string {
	return (getConfig().downloadUrl ?? '').replace(/\/+$/, '');
}

function getNonce(): string {
	return getConfig().nonce ?? '';
}

/**
 * Returns the endpoint suffix based on context.
 * Customer-facing pages use `/customer` endpoints.
 */
function getEndpointSuffix(context?: string): string {
	return context === 'my-account' ? '/customer' : '';
}

export function downloadBlob(blob: Blob, filename: string): void {
	const url = URL.createObjectURL(blob);
	const a = document.createElement('a');
	a.href = url;
	a.download = filename;
	a.style.display = 'none';
	document.body.appendChild(a);
	a.click();
	setTimeout(() => {
		URL.revokeObjectURL(url);
		a.remove();
	}, 1000);
}

export async function fetchInvoiceContext(
	orderId: number,
	nonce: string,
	context?: string,
): Promise<{
	orderId: number;
	designSlug: string;
	mergeTags: Record<string, unknown>;
	isGenerated: boolean;
	generationMode: 'automatic' | 'manual';
}> {
	const suffix = getEndpointSuffix(context);
	const res = await fetch(`${getBaseUrl()}/${orderId}/invoice-context${suffix}`, {
		method: 'GET',
		credentials: 'include',
		headers: { 'X-WP-Nonce': nonce },
	});
	if (!res.ok) {
		const text = await res.text().catch(() => '');
		const err = new Error(`Failed to fetch invoice context (status ${res.status})`);
		(err as any).status = res.status;
		(err as any).body = text;
		throw err;
	}
	return res.json();
}

export async function downloadExistingInvoice(
	orderId: number,
	nonce: string,
	context?: string,
): Promise<void> {
	const suffix = getEndpointSuffix(context);
	const res = await fetch(`${getBaseUrl()}/${orderId}/invoice${suffix}`, {
		method: 'GET',
		credentials: 'include',
		headers: { 'X-WP-Nonce': nonce },
	});
	if (!res.ok) throw new Error(`Download failed with status ${res.status}`);
	const data = (await res.json()) as { filename: string; pdf: string };
	const binary = atob(data.pdf);
	const bytes = new Uint8Array(binary.length);
	for (let i = 0; i < binary.length; i++) {
		bytes[i] = binary.charCodeAt(i);
	}
	downloadBlob(new Blob([bytes], { type: 'application/pdf' }), data.filename);
}

export async function uploadInvoicePdf(
	orderId: number,
	blob: Blob,
	nonce: string,
	context?: string,
): Promise<void> {
	const arrayBuffer = await blob.arrayBuffer();
	const bytes = new Uint8Array(arrayBuffer);
	let binary = '';
	for (let i = 0; i < bytes.length; i++) {
		binary += String.fromCharCode(bytes[i]!);
	}

	const suffix = getEndpointSuffix(context);
	const res = await fetch(`${getBaseUrl()}/${orderId}/invoice${suffix}`, {
		method: 'POST',
		credentials: 'include',
		headers: {
			'X-WP-Nonce': nonce,
			'Content-Type': 'application/json',
		},
		body: JSON.stringify({ pdf: btoa(binary) }),
	});

	if (!res.ok) {
		const body = await res.json().catch(() => ({}));
		throw new Error((body as { message?: string })?.message || `Upload failed with status ${res.status}`);
	}
}

/**
 * Build the design endpoint URL for customer-facing pages.
 */
export function getCustomerDesignEndpoint(orderId: number): string {
	return `${getBaseUrl()}/${orderId}/invoice-design/customer`;
}

/**
 * Build the design endpoint URL for the admin order-edit page.
 * The /invoice-design route accepts admin users without an order_key.
 */
export function getAdminDesignEndpoint(orderId: number): string {
	return `${getBaseUrl()}/${orderId}/invoice-design`;
}
