/**
 * Responsive orders display using DataList.
 * Pagination is shared and rendered once at the bottom.
 */
import { useMemo, useCallback, useState } from 'react';
import { __ } from '@wordpress/i18n';
import { Flex, Button, Tooltip, Icon } from '@wordpress/components';
import { chevronRight } from '@wordpress/icons';
import { Pagination } from '@woocommerce/components';
import type { Order, PluginSettings } from '../../types';
import {
	DataList,
	CountryFlag,
	Badge,
	RenderWeight,
	type DataListColumn,
} from '../../shared/components';
import {
	formatRelativeDate,
	getCourierLogo,
	truncateText,
} from '../../shared/utils';
import { getOrderTotalWeight } from './utils/orderWeight';
import { StoreSettingsResponse } from 'types/settings';
import SelectServiceModal from './select-service-modal';
import { useParcel2goAuth } from './../../shared/hooks';

interface OrderTableProps {
	orders: Order[];
	total: number;
	settings: PluginSettings;
	page: number;
	rowsPerPage: number;
	onShipNow: (orderId: number) => void;
	onPageChange: (page: number) => void;
	isLoading?: boolean;
	selectedOrderIds?: number[];
	onSelectionChange?: (orderIds: number[]) => void;
	onBulkShipNow?: (orderIds: number[]) => void;
	onRefreshOrders?: () => void;
}

function useOrderColumns(
	onShipNow: (orderId: number) => void,
	isLinked: boolean,
	onOpenSelectServiceModal: (order: Order) => void
): DataListColumn<Order>[] {
	return useMemo<DataListColumn<Order>[]>(
		() => [
			{
				key: 'orderId',
				label: __('Order ID', 'parcel2go-shipping'),
				render: (order) => `#${order.number ?? order.id}`,
			},
			{
				key: 'flag',
				label: '',
				screenReaderLabel: __('Country', 'parcel2go-shipping'),
				render: (order) => {
					const code = (order.shipping?.country ?? '')
						.trim()
						.toUpperCase();
					return <CountryFlag countryCode={code} />;
				},
			},
			{
				key: 'customer',
				label: __('Customer', 'parcel2go-shipping'),
				render: (order) => order.customer?.name ?? '—',
			},
			{
				key: 'shipping',
				label: __('Shipping', 'parcel2go-shipping'),
				render: (order) => {
					const courierLogo = getCourierLogo(
						order.cheapestQuote?.service?.courierSlug
					);
					const shippingMethodTitle =
						order.shipping_method?.title ?? '';
					return (
						<Flex gap={2} justify="flex-start">
							<Tooltip
								text={
									shippingMethodTitle ||
									__('No zone', 'parcel2go-shipping')
								}
							>
								<span style={{ whiteSpace: 'nowrap' }}>
									<Badge
										tone={
											shippingMethodTitle
												? 'default'
												: 'warning'
										}
									>
										{truncateText(
											shippingMethodTitle,
											21
										) ||
											__('No zone', 'parcel2go-shipping')}
									</Badge>
								</span>
							</Tooltip>
							{isLinked ? (
								<>
									<Flex
										direction="row"
										gap={2}
										justify="flex-start"
										align="center"
										onClick={() => {
											order.bulkError === 'in-progress'
												? null
												: onOpenSelectServiceModal(
														order
													);
										}}
										style={{ width: 'auto', cursor: 'pointer' }}
									>
										<Icon icon={chevronRight} size={16} />
										{order.bulkError ? (
											<Badge tone="black">
												{__(
													order.bulkError,
													'parcel2go-shipping'
												)}
											</Badge>
										) : (
											<img
												src={courierLogo}
												alt={
													order.cheapestQuote?.service
														?.courierSlug
												}
												width={60}
											/>
										)}
									</Flex>
								</>
							) : null}
						</Flex>
					);
				},
			},
			{
				key: 'weight',
				label: __('Weight', 'parcel2go-shipping'),
				isNumeric: true,
				render: (order) => {
					const summary = getOrderTotalWeight(order);
					return (
						<RenderWeight
							formatted={summary.formatted}
							hasNoWeight={summary.hasNoWeight}
							hasPartialMissingWeight={
								summary.hasPartialMissingWeight
							}
							missingWeightItems={summary.missingWeightItems}
							missingWeightCount={summary.missingWeightCount}
						/>
					);
				},
			},
			{
				key: 'date',
				label: __('Date', 'parcel2go-shipping'),
				render: (order) => formatRelativeDate(order.date_created),
			},
			{
				key: 'action',
				label: __('Action', 'parcel2go-shipping'),
				render: (order) => {
					const isInProgress =
						order.p2g?.shipStatus === 'Booked' ||
						order.p2g?.shipStatus === 'Paid';

					return (
						<Button
							variant="primary"
							size="small"
							onClick={() => onShipNow(order.id)}
						>
							{isInProgress
								? __('View Progress', 'parcel2go-shipping')
								: __('Ship Now', 'parcel2go-shipping')}
						</Button>
					);
				},
			},
		],
		[onShipNow, isLinked, onOpenSelectServiceModal]
	);
}

const getOrderKey = (order: Order) => order.id;
const getOrderId = (order: Order) => order.id;

export default function OrderTable({
	orders,
	total,
	settings,
	page,
	rowsPerPage,
	onShipNow,
	onPageChange,
	isLoading = false,
	selectedOrderIds = [],
	onSelectionChange,
	onRefreshOrders,
}: OrderTableProps) {
	const { isLinked } = useParcel2goAuth();
	const [selectedOrder, setSelectedOrder] = useState<Order | null>(null);

	const openSelectServiceModal = useCallback((order: Order) => {
		setSelectedOrder(order);
	}, []);

	const columns = useOrderColumns(
		onShipNow,
		isLinked,
		openSelectServiceModal
	);

	const handleSelectionChange = useCallback(
		(ids: number[]) => onSelectionChange?.(ids),
		[onSelectionChange]
	);

	if (!orders.length && !total && !isLoading) return null;

	return (
		<Flex direction="column" gap={4}>
			{selectedOrder && (
				<SelectServiceModal
					onClose={() => setSelectedOrder(null)}
					onRefreshOrders={onRefreshOrders}
					order={selectedOrder}
					settings={settings}
				/>
			)}
			<DataList<Order>
				items={orders}
				columns={columns}
				getKey={getOrderKey}
				isLoading={isLoading}
				skeletonRows={rowsPerPage}
				emptyMessage={__(
					'No processing orders found.',
					'parcel2go-shipping'
				)}
				selectable={isLinked}
				selectedIds={selectedOrderIds}
				onSelectionChange={handleSelectionChange}
				getId={getOrderId}
				isDisabled={(order) => !!order.bulkError}
			/>
			{!isLoading && total > rowsPerPage && (
				<Flex justify="center">
					<Pagination
						page={page}
						perPage={rowsPerPage}
						total={total}
						onPageChange={onPageChange}
					/>
				</Flex>
			)}
		</Flex>
	);
}
