import {
	NESTED_CHILD_FOCUS_BOX_STYLE,
	useNestedElementChromeState,
} from '@pdfdraft/core/lib/elementSelection';
import type { Element } from '@pdfdraft/core/stores/editor.store.types';
import React, { memo, useState } from 'react';
import { ElementToolbar } from '@pdfdraft/core/extensions';
import { ElementControls } from '../../../../../../pdfdraft/resources/editor/core/components/editor/slot-fill/ElementControls';
import { useEditorActions } from '@pdfdraft/core/stores/editor.store';
import { ColorControl } from '../../../../../../pdfdraft/resources/editor/core/components/rich-text/ColorPicker';
import { TypographyControl, TypographyFamilyControl, TypographyWeightControl, ProGate } from '@pdfdraft/core/components';
import { featureGate } from '@pdfdraft/core/lib/feature-gate';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClient } from '../../../elements/data-field/query-client';
import { Switch } from '@pdfdraft/ui/components/switch';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@pdfdraft/ui/components/tooltip';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@pdfdraft/ui/components/select';
import { __ } from '@wordpress/i18n';
import {
	DEFAULT_TOTAL_BLOCK_SETTINGS,
	TOTAL_BLOCK_NAMESPACE,
	type TotalBlockSettings,
} from '../constants/types';

type TotalBlockProps = {
	data: Element;
	isSelected: boolean;
} & React.HTMLAttributes<HTMLDivElement>;

type TotalMap = {
	subtotal: number;
	total_discount: number;
	total_tax: number;
	grand_total: number;
};

function toNumber(value: unknown): number {
	if (typeof value === 'number') return Number.isFinite(value) ? value : 0;
	if (typeof value === 'string') {
		const n = Number.parseFloat(value.replace(/,/g, ''));
		return Number.isFinite(n) ? n : 0;
	}
	return 0;
}

function getPreviewTotals(): TotalMap {
	const order = (window as any)?._PDFDRAFT_PDF_INVOICES_FOR_WOOCOMMERCE_ORDER_DATA_ as
		| {
				currency_symbol?: string;
				currency?: string;
				subtotal?: number | string;
				discount_total?: number | string;
				total_tax?: number | string;
				total?: number | string;
			}
		| undefined;

	if (!order) {
		// Consistent with product table dummy data: $20 + $40 = $60
		return {
			subtotal: 60,
			total_discount: 0,
			total_tax: 5.4,
			grand_total: 65.4,
		};
	}

	return {
		subtotal: toNumber(order.subtotal),
		total_discount: toNumber(order.discount_total),
		total_tax: toNumber(order.total_tax),
		grand_total: toNumber(order.total),
	};
}

function getPreviewCurrency(): string {
	const order = (window as any)?._PDFDRAFT_PDF_INVOICES_FOR_WOOCOMMERCE_ORDER_DATA_ as
		| { currency_symbol?: string; currency?: string }
		| undefined;
	const symbol = String(order?.currency_symbol ?? '').trim();
	if (symbol) return symbol;
	const code = String(order?.currency ?? '').trim();
	if (code) return code;
	return '$';
}

export const TotalBlock = memo(
	({ data, isSelected: _isSelected, style: divStyle, ...divProps }: TotalBlockProps) => {
		const { updateElement } = useEditorActions(['updateElement']);
		const { showChrome, showNestedChildFocus } =
			useNestedElementChromeState(data.id);
		const [alignSelectOpen, setAlignSelectOpen] = useState(false);
		const props: TotalBlockSettings = {
			...DEFAULT_TOTAL_BLOCK_SETTINGS,
			...(data.props ?? {}),
		};
		const totals = getPreviewTotals();
		const currency = getPreviewCurrency();
		const textColor = props.textStyle?.color;
		const textFontFamily = props.textStyle?.fontFamily;
		const textFontWeight = props.textStyle?.fontWeight;
		const textAlign = props.textAlign ?? 'right';

		const patchToggle = (
			key: keyof Pick<TotalBlockSettings, 'showSubtotal' | 'showDiscount' | 'showTax'>,
			value: boolean,
		) => {
			updateElement(data.id, (prev: any) => ({
				...prev,
				props: {
					...(prev.props ?? {}),
					[key]: value,
				},
			}));
		};

		const patchTextStyle = (patch: Partial<NonNullable<TotalBlockSettings['textStyle']>>) => {
			updateElement(data.id, (prev: any) => ({
				...prev,
				props: {
					...(prev.props ?? {}),
					textStyle: {
						...(prev.props?.textStyle ?? {}),
						...patch,
					},
				},
			}));
		};

		const patchProp = (patch: Partial<TotalBlockSettings>) => {
			updateElement(data.id, (prev: any) => ({
				...prev,
				props: { ...(prev.props ?? {}), ...patch },
			}));
		};

		const rows = [
			props.showSubtotal
				? { label: __('Subtotal', 'pdfdraft-pdf-invoices-for-woocommerce'), amount: totals.subtotal }
				: null,
			props.showDiscount
				? { label: __('Discount', 'pdfdraft-pdf-invoices-for-woocommerce'), amount: totals.total_discount }
				: null,
			props.showTax
				? { label: __('Tax', 'pdfdraft-pdf-invoices-for-woocommerce'), amount: totals.total_tax }
				: null,
			{ label: __('Total', 'pdfdraft-pdf-invoices-for-woocommerce'), amount: totals.grand_total },
		].filter(Boolean) as Array<{ label: string; amount: number }>;

		return (
			<div
				{...divProps}
				style={{
					position: 'absolute',
					...(divStyle || {}),
					...(showNestedChildFocus ? NESTED_CHILD_FOCUS_BOX_STYLE : {}),
				}}
				data-id={data.id}
				data-type={TOTAL_BLOCK_NAMESPACE}
			>
				{showChrome && (
					<ElementToolbar>
						<div className="flex items-center gap-3 rounded-md bg-white px-3 py-[9px] shadow-[0px_6px_24px_0px_rgba(10,10,10,0.08)]">
							<QueryClientProvider client={queryClient}>
								<TypographyControl
									currentFontFamily={textFontFamily}
									currentFontWeight={textFontWeight}
									onFamilyChange={(font) => {
										const currentWeight = textFontWeight ?? '400';
										const hasCurrentWeight = font.variants.find(
											(x) => x.toString() === currentWeight,
										);
										const newWeight = hasCurrentWeight
											? currentWeight
											: font.defVariant === 'regular'
												? '400'
												: (font.defVariant ?? '400');
										patchTextStyle({ fontFamily: font.family, fontWeight: newWeight });
									}}
									onWeightChange={(weight) => patchTextStyle({ fontWeight: weight })}
								>
									<TypographyFamilyControl />
									<TypographyWeightControl />
								</TypographyControl>
							</QueryClientProvider>
							<ProGate locked={!featureGate.canChangeColors()}>
								<TooltipProvider delayDuration={0}>
									<Tooltip>
										<TooltipTrigger asChild>
											<span>
												<ColorControl
													currentColor={textColor}
													onColorChange={(v?: string) => patchTextStyle({ color: v })}
												/>
											</span>
										</TooltipTrigger>
										<TooltipContent align="center" side="bottom" sideOffset={10}>
											{__('Text Color', 'pdfdraft-pdf-invoices-for-woocommerce')}
										</TooltipContent>
									</Tooltip>
								</TooltipProvider>
							</ProGate>
							<TooltipProvider delayDuration={0}>
								<Tooltip open={alignSelectOpen ? false : undefined}>
									<TooltipTrigger asChild>
										<span>
											<Select
												value={textAlign}
												open={alignSelectOpen}
												onOpenChange={setAlignSelectOpen}
												onValueChange={(v: string) => patchProp({ textAlign: v as TotalBlockSettings['textAlign'] })}
											>
												<SelectTrigger className="h-auto w-auto gap-1 rounded border-input p-1 text-sm leading-[20px]">
													<SelectValue />
												</SelectTrigger>
												<SelectContent className="shadow-none">
													<SelectItem value="left">{__('Left', 'pdfdraft-pdf-invoices-for-woocommerce')}</SelectItem>
													<SelectItem value="center">{__('Center', 'pdfdraft-pdf-invoices-for-woocommerce')}</SelectItem>
													<SelectItem value="right">{__('Right', 'pdfdraft-pdf-invoices-for-woocommerce')}</SelectItem>
												</SelectContent>
											</Select>
										</span>
									</TooltipTrigger>
									<TooltipContent align="center" side="bottom" sideOffset={10}>
										{__('Alignment', 'pdfdraft-pdf-invoices-for-woocommerce')}
									</TooltipContent>
								</Tooltip>
							</TooltipProvider>
						</div>
					</ElementToolbar>
				)}

				{showChrome && (
					<ElementControls>
						<div>
							<p className="mb-3 text-xs font-semibold uppercase tracking-widest text-[#888]">
								{__('Rows', 'pdfdraft-pdf-invoices-for-woocommerce')}
							</p>
							<div className="space-y-2">
								{[
									{ label: __('Subtotal', 'pdfdraft-pdf-invoices-for-woocommerce'), checked: props.showSubtotal, key: 'showSubtotal' as const },
									{ label: __('Discount', 'pdfdraft-pdf-invoices-for-woocommerce'), checked: props.showDiscount, key: 'showDiscount' as const },
									{ label: __('Tax',      'pdfdraft-pdf-invoices-for-woocommerce'), checked: props.showTax,      key: 'showTax'      as const },
								].map((row) => (
									<div
										key={row.key}
										className="flex items-center justify-between rounded-xl border border-border/70 bg-white px-4 py-3"
									>
										<span className="text-sm font-medium text-[#1d2327]">{row.label}</span>
										<div style={{ transform: 'scale(0.9)', transformOrigin: 'right center', flexShrink: 0 }}>
											<Switch
												checked={row.checked}
												onCheckedChange={(v) => patchToggle(row.key, Boolean(v))}
											/>
										</div>
									</div>
								))}
							</div>
						</div>
					</ElementControls>
				)}

				<table
					style={{
						width: '100%',
						height: '100%',
						borderCollapse: 'collapse',
						tableLayout: 'fixed',
						fontSize: 13,
						lineHeight: 1.35,
						color: textColor || undefined,
						fontFamily: textFontFamily || undefined,
						fontWeight: textFontWeight || undefined,
					}}
				>
					<colgroup>
						<col style={{ width: '50%' }} />
						<col style={{ width: '50%' }} />
					</colgroup>
					<tbody>
						{rows.map((row) => (
							<tr key={row.label}>
								<td style={{ textAlign: textAlign as React.CSSProperties['textAlign'], padding: '4px 10px 4px 0', fontWeight: 600 }}>
									{row.label}
								</td>
								<td style={{ textAlign: textAlign as React.CSSProperties['textAlign'], padding: '4px 0', whiteSpace: 'nowrap' }}>
									{`${currency} ${String(row.amount)}`}
								</td>
							</tr>
						))}
					</tbody>
				</table>
			</div>
		);
	},
);
