import { memo, useMemo } from 'react';
import { __ } from '@wordpress/i18n';
import {
	Button,
	Card,
	CardBody,
	Flex,
	FlexBlock,
	FlexItem,
	Tooltip,
} from '@wordpress/components';
import { edit } from '@wordpress/icons';
import type { Order, OrderItemDimensions } from '../../types/order';
import type { Service } from '../../types/quote';
import type { Price } from '../../types/price';
import type {
	PluginSettings,
} from '../../types/settings';
import CourierBadge from '../../shared/components/courier-badge';
import { formatDisplayNumber } from '../../shared/utils';


interface ServiceGroup {
	service: Service;
	orders: Order[];
	count: number;
}

interface ValidationResult {
	success: boolean;
	price?: Price;
}

const ServiceGroupSection = memo(function ServiceGroupSection({
	serviceGroups,
}: {
	serviceGroups: ServiceGroup[];
}) {	
	return (
		<Flex direction="column" gap={3}>
			<h2 style={{ margin: 0, fontSize: '1rem', fontWeight: 600 }}>
				{__('Orders by Service', 'parcel2go-shipping')}
			</h2>
			<Flex direction="column" gap={2}>
				{serviceGroups?.map((group) => (
					<Card key={group.service.slug}>
						<CardBody>
							<Flex align="center" justify="space-between">
								<FlexItem>
									<CourierBadge
										slug={group.service.courierSlug}
										courier={group.service.courier}
										name={group.service.name}
										size={40}
									/>
								</FlexItem>
								<FlexItem>
									<span
										style={{
											display: 'inline-block',
											padding: '2px 10px',
											borderRadius: 12,
											background: '#e0f0ff',
											color: '#0c5eb5',
											fontSize: '0.85em',
											fontWeight: 500,
										}}
									>
										{`${group.count} ${group.count === 1 ? __('order', 'parcel2go-shipping') : __('orders', 'parcel2go-shipping')}`}
									</span>
								</FlexItem>
							</Flex>
						</CardBody>
					</Card>
				))}
			</Flex>
		</Flex>
	);
});


const PriceBreakdownSection = memo(function PriceBreakdownSection({
	price,
}: {
	price: Price;
}) {
	const fmt = (amount: number) => `£${(amount / 100).toFixed(2)}`;

	return (
		<Card>
			<CardBody>
				<Flex direction="column" gap={3}>
					<h3 style={{ margin: 0, fontSize: '1rem', fontWeight: 600 }}>
						{__('Price Breakdown', 'parcel2go-shipping')}
					</h3>

					<Flex direction="column" gap={1}>
						<Flex justify="space-between">
							<FlexItem>
								<span>{__('Subtotal (ex VAT)', 'parcel2go-shipping')}</span>
							</FlexItem>
							<FlexItem>
								<span style={{ fontWeight: 500 }}>{fmt(price.net)}</span>
							</FlexItem>
						</Flex>

						<Flex justify="space-between">
							<FlexItem>
								<span>{__('VAT', 'parcel2go-shipping')}</span>
							</FlexItem>
							<FlexItem>
								<span style={{ fontWeight: 500 }}>{fmt(price.tax)}</span>
							</FlexItem>
						</Flex>

						<hr style={{ margin: '8px 0', border: 'none', borderTop: '1px solid #ddd' }} />

						<Flex justify="space-between">
							<FlexItem>
								<span style={{ fontSize: '1.05em', fontWeight: 700 }}>
									{__('Total (inc VAT)', 'parcel2go-shipping')}
								</span>
							</FlexItem>
							<FlexItem>
								<span style={{ fontSize: '1.05em', fontWeight: 700 }}>
									{fmt(price.gross)}
								</span>
							</FlexItem>
						</Flex>
					</Flex>
				</Flex>
			</CardBody>
		</Card>
	);
});

export default function BulkShipBreakdown({
	validationResult,
	orders,
	defaultPackage,
	settings,
	onNavigateToSettings,
}: {
	validationResult: ValidationResult;
	orders: Order[];
	defaultPackage: OrderItemDimensions;
	settings: PluginSettings;
	/** Called when the user clicks the edit-settings button. */
	onNavigateToSettings?: () => void;
}) {
  const serviceGroups = useMemo(() => {
    // Group orders by service
    const groupMap = new Map<string, ServiceGroup>();

    orders.forEach((order) => {
      if (order.cheapestQuote) {
        const serviceSlug = order.cheapestQuote.service.slug;

        if (groupMap.has(serviceSlug)) {
          const existing = groupMap.get(serviceSlug)!;
          existing.orders.push(order);
          existing.count += 1;
        } else {
          groupMap.set(serviceSlug, {
            service: order.cheapestQuote.service,
            orders: [order],
            count: 1,
          });
        }
      }
    });

    // Convert to array and sort by count (descending) then by service name
    return Array.from(groupMap.values()).sort((a, b) => {
      if (b.count !== a.count) {
        return b.count - a.count;
      }
      return a.service.name.localeCompare(b.service.name);
    });
  }, [orders]) as ServiceGroup[];

  const ordersWithoutService = orders?.filter((order) => !order.cheapestQuote) ?? [];

  const origin = settings?.shipping;
	const dimensionUnit = orders?.[0]?.units?.dimension || settings?.units?.dimension || 'cm';

	const dimensions = useMemo(() => {
		let max_length = 0;
		let max_width = 0;
		let max_height = 0;
		let max_weight = 0;

		orders[0].items?.forEach((item) => {
			max_length = Math.max(max_length, item.dimensions.length);
			max_width = Math.max(max_width, item.dimensions.width);
			max_height = Math.max(max_height, item.dimensions.height);
			max_weight = Math.max(max_weight, item.dimensions.weight);
		});
		return {
			length: max_length || defaultPackage?.length,
			width: max_width || defaultPackage?.width,
			height: max_height || defaultPackage?.height,
			weight: max_weight || defaultPackage?.weight,
		};
	}, [orders, defaultPackage]);

	return (
		<Flex direction="column" gap={4}>
			{/* Order details */}
			<Card>
				<CardBody>
					<Flex direction="column" gap={1}>
						<Flex justify="space-between" align="center">
							<FlexBlock>
								<h3 style={{ margin: 0, fontSize: '1rem', fontWeight: 600 }}>
									{__('Order Details', 'parcel2go-shipping')}
								</h3>
							</FlexBlock>
							<FlexItem>
								<Tooltip
									text={__('Edit default order settings', 'parcel2go-shipping')}
								>
									<Button
										variant="tertiary"
										icon={edit}
										size="small"
										onClick={onNavigateToSettings}
										label={__('Edit order settings', 'parcel2go-shipping')}
									/>
								</Tooltip>
							</FlexItem>
						</Flex>

						<p style={{ margin: '4px 0 0' }}>
							<span style={{ fontWeight: 500 }}>
								{__('Store location :', 'parcel2go-shipping')}
							</span>{' '}
							{[origin.property, origin.street, origin.town, origin.postcode]
								.filter(Boolean)
								.join(' ')}
						</p>

						<p style={{ margin: '4px 0 0' }}>
							<span style={{ fontWeight: 500 }}>
								{__('Packaging :', 'parcel2go-shipping')}
							</span>{' '}
							{`${formatDisplayNumber(Number(dimensions?.length ?? 0))} x ${formatDisplayNumber(Number(dimensions?.width ?? 0))} x ${formatDisplayNumber(Number(dimensions?.height ?? 0))} ${dimensionUnit}`}
						</p>
					</Flex>
				</CardBody>
			</Card>

			{/* Service groups */}
			{serviceGroups?.length > 0 && (
				<ServiceGroupSection serviceGroups={serviceGroups} />
			)}

			{/* Price breakdown */}
			{validationResult.success && validationResult.price && (
				<PriceBreakdownSection price={validationResult.price} />
			)}

			{/* Orders without a service */}
			{ordersWithoutService.length > 0 && (
				<Card>
					<CardBody>
						<Flex direction="column" gap={2}>
							<h3 style={{ margin: 0, fontSize: '1rem', fontWeight: 600, color: '#cc1818' }}>
								{__('Orders without assigned service', 'parcel2go-shipping')}
							</h3>
							<span
								style={{
									display: 'inline-block',
									padding: '2px 10px',
									borderRadius: 12,
									background: '#fcecec',
									color: '#cc1818',
									fontSize: '0.85em',
									fontWeight: 500,
									width: 'fit-content',
								}}
							>
								{`${ordersWithoutService.length} ${ordersWithoutService.length === 1 ? __('order', 'parcel2go-shipping') : __('orders', 'parcel2go-shipping')}`}
							</span>
						</Flex>
					</CardBody>
				</Card>
			)}
		</Flex>
	);
}