import type { ActivityLogRow, AdminData, DebugStatus, DemandReportRow, Settings, OverviewData, Subscriber, WaitlistProduct, WaitlistSubscriptionRow } from './types';
import { __ } from '@wordpress/i18n';

function requireDashboardAdmin(): AdminData {
	const a = window.stockbeaconAdmin;
	if (!a?.restUrl || !a.nonce) {
		throw new Error( __( 'Admin configuration missing', 'stockbeacon-product-waitlists-for-woocommerce' ) );
	}
	return a;
}

export async function requestJson<T = unknown>(url: string, options: RequestInit = {}): Promise<T> {
	const res = await fetch(url, options);
	const data = await res.json().catch(() => ({})) as Record<string, unknown>;
	if (!res.ok) {
		const msg = (data?.message ?? data?.code ?? res.statusText ?? __( 'Request failed', 'stockbeacon-product-waitlists-for-woocommerce' )) as unknown;
		throw new Error(typeof msg === 'string' ? msg : __( 'Request failed', 'stockbeacon-product-waitlists-for-woocommerce' ));
	}
	return data as T;
}

export function apiHeaders(): HeadersInit {
	const a = requireDashboardAdmin();
	return {
		'Content-Type': 'application/json',
		'X-WP-Nonce': a.nonce,
	};
}

export function readHeaders(): HeadersInit {
	return { 'X-WP-Nonce': requireDashboardAdmin().nonce };
}

export async function fetchSettings(): Promise<Settings> {
	const a = requireDashboardAdmin();
	return requestJson<Settings>(a.restUrl + '/settings', {
		headers: readHeaders(),
		credentials: 'same-origin',
	});
}

export async function saveSettings(payload: Partial<Settings>): Promise<void> {
	const a = requireDashboardAdmin();
	await requestJson(a.restUrl + '/settings', {
		method: 'PUT',
		headers: apiHeaders(),
		body: JSON.stringify(payload),
	});
}

export async function fetchOverview(search = ''): Promise<OverviewData> {
	const params = new URLSearchParams();
	const trimmed = search.trim();
	if (trimmed) params.set('search', trimmed);
	const a = requireDashboardAdmin();
	const url = a.restUrl + '/overview' +
		(params.toString() ? '?' + params.toString() : '');
	return requestJson<OverviewData>(url, { headers: readHeaders(), credentials: 'same-origin' });
}

export async function fetchSubscribers(search = '', perPage = 50, status = '', dateFrom = '', dateTo = ''): Promise<Subscriber[]> {
	const params = new URLSearchParams({
		per_page: String(perPage),
	});
	const trimmed = search.trim();
	if (trimmed) params.set('search', trimmed);
	if (status) params.set('status', status);
	if (dateFrom) params.set('date_from', dateFrom);
	if (dateTo) params.set('date_to', dateTo);
	const a = requireDashboardAdmin();
	return requestJson<Subscriber[]>(`${a.restUrl}/subscribers?${params.toString()}`, {
		headers: readHeaders(),
		credentials: 'same-origin',
	});
}

export async function fetchWaitlists(perPage = 100, page = 1, mode = ''): Promise<WaitlistProduct[]> {
	const a = requireDashboardAdmin();
	const params = new URLSearchParams({
		per_page: String(perPage),
		page: String(page),
	});
	if (mode) params.set('mode', mode);
	const url = `${a.restUrl}/waitlists?${params.toString()}`;
	return requestJson<WaitlistProduct[]>(url, { headers: readHeaders(), credentials: 'same-origin' });
}

export async function updateWaitlistProductVisibility(productId: number, visible: boolean): Promise<WaitlistProduct> {
	const a = requireDashboardAdmin();
	return requestJson<WaitlistProduct>(`${a.restUrl}/waitlists/${productId}`, {
		method: 'PUT',
		headers: apiHeaders(),
		credentials: 'same-origin',
		body: JSON.stringify({ waitlist_form_visible: visible }),
	});
}

export async function fetchActivityLogs(perPage = 50, page = 1, search = '', type = '', delivery = ''): Promise<ActivityLogRow[]> {
	const a = requireDashboardAdmin();
	const params = new URLSearchParams({
		per_page: String(perPage),
		page: String(page),
	});
	const trimmed = search.trim();
	if (trimmed) params.set('search', trimmed);
	if (type) params.set('type', type);
	if (delivery) params.set('delivery', delivery);
	const url = `${a.restUrl}/activity?${params.toString()}`;
	return requestJson<ActivityLogRow[]>(url, { headers: readHeaders(), credentials: 'same-origin' });
}

export async function fetchDebugStatus(): Promise<DebugStatus> {
	const a = requireDashboardAdmin();
	return requestJson<DebugStatus>(`${a.restUrl}/debug/status`, {
		headers: readHeaders(),
		credentials: 'same-origin',
	});
}



export async function scheduleDebugBatch(productId: number, variationId = 0): Promise<{ success: boolean; message?: string }> {
	const a = requireDashboardAdmin();
	return requestJson<{ success: boolean; message?: string }>(`${a.restUrl}/debug/test-batch`, {
		method: 'POST',
		headers: apiHeaders(),
		credentials: 'same-origin',
		body: JSON.stringify({ product_id: productId, variation_id: variationId }),
	});
}

export async function deleteSubscriber(id: number): Promise<void> {
	const a = requireDashboardAdmin();
	await requestJson(`${a.restUrl}/subscribers/${id}`, {
		method: 'DELETE',
		headers: readHeaders(),
		credentials: 'same-origin',
	});
}

export async function deleteWaitlist(productId: number): Promise<{ deleted: number }> {
	const a = requireDashboardAdmin();
	return requestJson<{ deleted: number }>(
		`${a.restUrl}/waitlists/${productId}`,
		{ method: 'DELETE', headers: readHeaders(), credentials: 'same-origin' },
	);
}

export async function sendTestEmail(to: string, extraPayload?: Record<string, unknown>): Promise<void> {
	const a = requireDashboardAdmin();
	await requestJson(`${a.restUrl}/email/test`, {
		method: 'POST',
		headers: apiHeaders(),
		credentials: 'same-origin',
		body: JSON.stringify({ to, ...extraPayload }),
	});
}

export async function seedDebugSubscribers(productId: number, variationId = 0, count = 3): Promise<{ success: boolean; created: string[]; message?: string }> {
	const a = requireDashboardAdmin();
	return requestJson<{ success: boolean; created: string[]; message?: string }>(`${a.restUrl}/debug/seed-subscribers`, {
		method: 'POST',
		headers: apiHeaders(),
		credentials: 'same-origin',
		body: JSON.stringify({ product_id: productId, variation_id: variationId, count }),
	});
}

export async function clearTestSubscribers(): Promise<{ success: boolean; deleted: number; message?: string }> {
	const a = requireDashboardAdmin();
	return requestJson<{ success: boolean; deleted: number; message?: string }>(`${a.restUrl}/debug/seed-subscribers`, {
		method: 'DELETE',
		headers: apiHeaders(),
		credentials: 'same-origin',
	});
}

export async function fetchWaitlistRowsForProduct(productId: number): Promise<WaitlistSubscriptionRow[]> {
	const cfg = window.stockbeaconProduct;
	if (!cfg?.restUrl || !cfg.nonce) {
		throw new Error( __( 'Missing REST configuration', 'stockbeacon-product-waitlists-for-woocommerce' ) );
	}
	return requestJson<WaitlistSubscriptionRow[]>(
		`${cfg.restUrl}/waitlists/${productId}`,
		{
			headers: { 'X-WP-Nonce': cfg.nonce },
			credentials: 'same-origin',
		}
	);
}
