import { type SettingsSelectOption } from '@pdfdraft/core/components';
import apiFetch from '@wordpress/api-fetch';
import { __ } from '@wordpress/i18n';
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { getWooCommerceSettingsLocalized } from './utils';
import { SettingsSkeleton } from './setttings-skeleton';
import { SECTION_COMPONENTS } from './sections/registry';
import type { SectionProps } from './sections/types';

declare global {
	interface Window {
		__pdfdraftSaveFunctions?: Map<string, () => Promise<boolean>>;
	}
}

/** Fired by the main settings sidebar when the active nav item changes. */
const NAV_EVENT = 'pdfdraft:settings:nav';

const REST_BASE = 'pdfdraft/v1/woocommerce/settings';

// ─── Types ────────────────────────────────────────────────────────────────────

type GenerationMode = 'automatic' | 'manual';
type InvoiceNumberMode = 'order_id' | 'sequential';

interface WooCommerceSettings {
	general: {
		invoice_settings: {
			generation_mode: GenerationMode;
			disable_free_order_invoices: boolean;
			invoice_number_mode: InvoiceNumberMode;
			invoice_number_start: number;
			show_my_account_download_button: boolean;
			invoice_prefix: string;
			invoice_suffix: string;
			storage_custom_folder: string;
			storage_organize_by_date: boolean;
		};
	};
}

// ─── Data fetching ────────────────────────────────────────────────────────────

function fetchSettings(): Promise<WooCommerceSettings> {
	return apiFetch<WooCommerceSettings>({ path: REST_BASE });
}

function useSettings() {
	return useQuery({
		queryKey: ['pdfdraft-pdf-invoices-for-woocommerce-settings'],
		queryFn: fetchSettings,
	});
}

function useSaveSettings() {
	const queryClient = useQueryClient();
	return useMutation({
		mutationFn: (body: WooCommerceSettings) =>
			apiFetch<WooCommerceSettings>({
				path: REST_BASE,
				method: 'POST',
				data: body,
			}),
		onSuccess: (data) => {
			queryClient.setQueryData(['pdfdraft-pdf-invoices-for-woocommerce-settings'], data);
		},
	});
}

// ─── Localized data ───────────────────────────────────────────────────────────

const localizedData = getWooCommerceSettingsLocalized<{
	sections?: Array<{ key: string; label: string }>;
	generation_mode_options?: SettingsSelectOption[];
	invoice_number_mode_options?: SettingsSelectOption[];
}>() ?? {};

/** Default to the first section key registered in the PHP Registry (e.g. 'invoices'). */
const DEFAULT_SECTION_KEY = localizedData.sections?.[0]?.key ?? 'invoices';

const GENERATION_MODE_OPTIONS: SettingsSelectOption[] = localizedData.generation_mode_options ?? [];
const INVOICE_NUMBER_MODE_OPTIONS: SettingsSelectOption[] = localizedData.invoice_number_mode_options ?? [];

// ─── Settings section component ───────────────────────────────────────────────

/**
 * WooCommerce Invoices settings section.
 *
 * Rendered inside the unified PDFDraft settings page as an addon section.
 * Page chrome (header, sidebar, Save button) is handled by the parent page —
 * this component only renders its own inner navigation and content.
 *
 * The component registers its async save function in `window.__pdfdraftSaveFunctions`
 * so the parent page's Save button can trigger it.
 */
export function SettingsPage() {
	const { data, isLoading, isError } = useSettings();
	const saveMutation = useSaveSettings();

	// ── Active invoice-template design ────────────────────────────────────────
	const { data: activeDesignData } = useQuery({
		queryKey: ['woo-active-design'],
		queryFn: () => apiFetch<{ slug: string }>({ path: '/pdfdraft/v1/woocommerce/active-design' }),
		staleTime: 30_000,
		refetchOnWindowFocus: false,
	});
	const [localActiveDesignSlug, setLocalActiveDesignSlug] = useState<string | null>(null);
	const activeDesignInitializedRef = useRef(false);

	if (activeDesignData && !activeDesignInitializedRef.current) {
		activeDesignInitializedRef.current = true;
		setLocalActiveDesignSlug(activeDesignData.slug ?? '');
	}

	const [activeItem, setActiveItem] = useState<string>(DEFAULT_SECTION_KEY);

	// Sync active item when the main settings sidebar dispatches a nav event.
	useEffect(() => {
		const handler = (e: Event) => {
			const { section, child } = (e as CustomEvent<{ section: string; child: string | null }>).detail;
			if (section === 'woocommerce-invoices' && child) {
				setActiveItem(child);
			}
		};
		window.addEventListener(NAV_EVENT, handler);
		return () => window.removeEventListener(NAV_EVENT, handler);
	}, []);
	const [localMode, setLocalMode] = useState<GenerationMode | null>(null);
	const [localInvoiceNumberMode, setLocalInvoiceNumberMode] = useState<InvoiceNumberMode | null>(null);
	const [localInvoiceNumberStart, setLocalInvoiceNumberStart] = useState<string>('');
	const [showMyAccountDownloadButton, setShowMyAccountDownloadButton] = useState<boolean | null>(null);
	const [localInvoicePrefix, setLocalInvoicePrefix] = useState<string | null>(null);
	const [localInvoiceSuffix, setLocalInvoiceSuffix] = useState<string | null>(null);
	const [localStorageFolder, setLocalStorageFolder] = useState<string | null>(null);
	const [localStorageByDate, setLocalStorageByDate] = useState<boolean | null>(null);
	const [localDisableFreeOrderInvoices, setLocalDisableFreeOrderInvoices] = useState<boolean | null>(null);
	const initializedRef = useRef(false);

	if (data && !initializedRef.current) {
		initializedRef.current = true;
		setLocalMode(data.general.invoice_settings.generation_mode ?? 'automatic');
		setLocalInvoiceNumberMode(data.general.invoice_settings.invoice_number_mode ?? 'order_id');
		setLocalInvoiceNumberStart(String(data.general.invoice_settings.invoice_number_start ?? 1));
		setShowMyAccountDownloadButton(data.general.invoice_settings.show_my_account_download_button ?? true);
		setLocalInvoicePrefix(data.general.invoice_settings.invoice_prefix ?? '');
		setLocalInvoiceSuffix(data.general.invoice_settings.invoice_suffix ?? '');
		setLocalStorageFolder(data.general.invoice_settings.storage_custom_folder ?? '');
		setLocalStorageByDate(data.general.invoice_settings.storage_organize_by_date ?? false);
		setLocalDisableFreeOrderInvoices(data.general.invoice_settings.disable_free_order_invoices ?? false);
	}

	const currentMode = localMode ?? (data?.general.invoice_settings.generation_mode ?? 'automatic');
	const currentInvoiceNumberMode =
		localInvoiceNumberMode ?? (data?.general.invoice_settings.invoice_number_mode ?? 'order_id');
	const currentInvoiceNumberStartRaw =
		localInvoiceNumberStart !== ''
			? localInvoiceNumberStart
			: String(data?.general.invoice_settings.invoice_number_start ?? 1);
	const currentShowMyAccountDownloadButton =
		showMyAccountDownloadButton ?? (data?.general.invoice_settings.show_my_account_download_button ?? true);
	const currentInvoicePrefix =
		localInvoicePrefix !== null ? localInvoicePrefix : (data?.general.invoice_settings.invoice_prefix ?? '');
	const currentInvoiceSuffix =
		localInvoiceSuffix !== null ? localInvoiceSuffix : (data?.general.invoice_settings.invoice_suffix ?? '');
	const currentStorageFolder =
		localStorageFolder !== null ? localStorageFolder : (data?.general.invoice_settings.storage_custom_folder ?? '');
	const currentStorageByDate =
		localStorageByDate !== null ? localStorageByDate : (data?.general.invoice_settings.storage_organize_by_date ?? false);
	const currentDisableFreeOrderInvoices =
		localDisableFreeOrderInvoices !== null
			? localDisableFreeOrderInvoices
			: (data?.general.invoice_settings.disable_free_order_invoices ?? false);

	const currentActiveDesignSlug = localActiveDesignSlug ?? (activeDesignData?.slug ?? '');

	/** Async save — returns true on success, false on error. */
	const handleSave = useCallback(async (): Promise<boolean> => {
		try {
			await saveMutation.mutateAsync({
				general: {
					invoice_settings: {
						generation_mode:                 currentMode,
						disable_free_order_invoices:     currentDisableFreeOrderInvoices,
						invoice_number_mode:             currentInvoiceNumberMode,
						invoice_number_start:
							currentInvoiceNumberMode === 'sequential'
								? Math.max(1, Number.parseInt(currentInvoiceNumberStartRaw || '1', 10) || 1)
								: 1,
						show_my_account_download_button: currentShowMyAccountDownloadButton,
						invoice_prefix:                  currentInvoicePrefix,
						invoice_suffix:                  currentInvoiceSuffix,
						storage_custom_folder:           currentStorageFolder,
						storage_organize_by_date:        currentStorageByDate,
					},
				},
			});

			// Save active invoice-template design.
			// Always call the endpoint when the user has explicitly interacted with the
			// selector (localActiveDesignSlug !== null), including when they cleared it
			// back to the empty option. Also re-save when an existing slug is loaded so
			// it is preserved on every settings save.
			const shouldSaveDesign = localActiveDesignSlug !== null || Boolean(activeDesignData?.slug);
			if (shouldSaveDesign) {
				await apiFetch({
					path:   '/pdfdraft/v1/woocommerce/active-design',
					method: 'POST',
					data:   { slug: currentActiveDesignSlug },
				});
			}

			return true;
		} catch {
			return false;
		}
	}, [
		saveMutation,
		currentMode,
		currentDisableFreeOrderInvoices,
		currentInvoiceNumberMode,
		currentInvoiceNumberStartRaw,
		currentShowMyAccountDownloadButton,
		currentInvoicePrefix,
		currentInvoiceSuffix,
		currentStorageFolder,
		currentStorageByDate,
		currentActiveDesignSlug,
		localActiveDesignSlug,
		activeDesignData,
	]);

	// Keep a ref so the registry always calls the latest version of handleSave
	// without needing to re-register on every state change.
	const handleSaveRef = useRef(handleSave);
	useLayoutEffect(() => {
		handleSaveRef.current = handleSave;
	});

	// Register save function in the global registry (once).
	useEffect(() => {
		window.__pdfdraftSaveFunctions ??= new Map();
		window.__pdfdraftSaveFunctions.set('woocommerce-invoices', () => handleSaveRef.current());
		return () => {
			window.__pdfdraftSaveFunctions?.delete('woocommerce-invoices');
		};
	}, []); // eslint-disable-line react-hooks/exhaustive-deps

	const sectionProps: SectionProps = {
		sectionKey:                       activeItem,
		localizedData:                    localizedData as Record<string, unknown>,
		currentMode,
		disableFreeOrderInvoices:         currentDisableFreeOrderInvoices,
		onDisableFreeOrderInvoicesChange: (v) => setLocalDisableFreeOrderInvoices(v),
		currentInvoiceNumberMode,
		localInvoiceNumberStart,
		onGenerationModeChange:           (v) => setLocalMode(v as GenerationMode),
		onInvoiceNumberModeChange:        (v) => setLocalInvoiceNumberMode(v as InvoiceNumberMode),
		onInvoiceNumberStartChange:       (v) => setLocalInvoiceNumberStart(v),
		showMyAccountDownloadButton:      currentShowMyAccountDownloadButton,
		onMyAccountDownloadButtonChange:  (v) => setShowMyAccountDownloadButton(v),
		invoicePrefix:                    currentInvoicePrefix,
		invoiceSuffix:                    currentInvoiceSuffix,
		onInvoicePrefixChange:            (v) => setLocalInvoicePrefix(v),
		onInvoiceSuffixChange:            (v) => setLocalInvoiceSuffix(v),
		storageCustomFolder:              currentStorageFolder,
		storageOrganizeByDate:            currentStorageByDate,
		onStorageCustomFolderChange:      (v) => setLocalStorageFolder(v),
		onStorageOrganizeByDateChange:    (v) => setLocalStorageByDate(v),
		generationModeOptions:            GENERATION_MODE_OPTIONS,
		invoiceNumberModeOptions:         INVOICE_NUMBER_MODE_OPTIONS,
		activeDesignSlug:                 currentActiveDesignSlug,
		onActiveDesignSlugChange:         (slug: string) => setLocalActiveDesignSlug(slug),
	};

	const ActiveSectionComponent = SECTION_COMPONENTS[activeItem] ?? null;

	if (isLoading) return <SettingsSkeleton />;

	if (isError) {
		return (
			<div style={{ padding: '24px 32px', color: '#d63638', fontSize: '13px' }}>
				{__('Failed to load settings.', 'pdfdraft-pdf-invoices-for-woocommerce')}
			</div>
		);
	}

	return (
		<div style={{ padding: '24px 32px', minHeight: 0 }}>
			<div className="space-y-6">
				{ActiveSectionComponent ? (
					<ActiveSectionComponent {...sectionProps} />
				) : (
					<p style={{ fontSize: '13px', color: '#646970' }}>
						{__('No settings found for this section.', 'pdfdraft-pdf-invoices-for-woocommerce')}
					</p>
				)}
			</div>
		</div>
	);
}
