/**
 * Reusable: dropdown to select a courier from quotes + list of selected couriers with remove.
 * Use with useQuotesFetcher; parent controls when to fetch and passes fetcher state.
 */
import { __, sprintf } from '@wordpress/i18n';
import { memo, useState, useEffect, useCallback } from '@wordpress/element';
import {
	Flex,
	Notice,
	Button,
	Dropdown,
	MenuGroup,
	MenuItem,
} from '@wordpress/components';
import { chevronDown } from '@wordpress/icons';
import { Spinner } from '@woocommerce/components';
import type { Quote, Service } from '../../types/quote';
import { getCourierLogo } from '../utils/getAsset';

const REMOVED_NOTICE_DURATION_MS = 4000;

function pillStyle(background: string, color: string) {
	return {
		display: 'inline-flex' as const,
		alignItems: 'center' as const,
		gap: 6,
		padding: '2px 8px',
		borderRadius: 12,
		background,
		color,
		fontSize: 12,
		lineHeight: 1.4,
	};
}

export interface CourierSelectWithListProps {
	/** Call when user focuses the select to trigger quote fetch. */
	onOpenDropdown: () => void | boolean;
	quotesList: Quote[];
	quotesLoading: boolean;
	quotesError: string | null;
	/** Selected services with courier name and slug for logo display. */
	selectedCouriers: Service[];
	/** Called when user selects a courier from quotes. */
	onAddCourier: (service: Service) => void;
	/** Called when user removes a selected courier. */
	onRemoveCourier: (service: Service) => void;
	disabled?: boolean;
	canFetch: boolean;
	missingMessage: string | null;
	clearAllButton?: {
		label: string;
		onClick: () => void;
		disabled?: boolean;
		isBusy?: boolean;
	};
}

function CourierSelectWithListInner({
	onOpenDropdown,
	quotesList,
	quotesLoading,
	quotesError,
	selectedCouriers,
	onAddCourier,
	onRemoveCourier,
	disabled = false,
	canFetch,
	missingMessage,
	clearAllButton,
}: CourierSelectWithListProps) {
	const [lastRemovedCourier, setLastRemovedCourier] = useState<string | null>(
		null
	);

	useEffect(() => {
		if (!lastRemovedCourier) return;
		const id = window.setTimeout(
			() => setLastRemovedCourier(null),
			REMOVED_NOTICE_DURATION_MS
		);
		return () => clearTimeout(id);
	}, [lastRemovedCourier]);

	const handleRemoveCourier = useCallback(
		(service: Service) => {
			onRemoveCourier(service);
			const displayName = service.courier || service.name;
			setLastRemovedCourier(displayName);
		},
		[onRemoveCourier]
	);

	return (
		<Flex direction="column" gap={2}>
			{missingMessage && !canFetch && !disabled && (
				<Notice status="warning" isDismissible={false}>
					{missingMessage}
				</Notice>
			)}
			{lastRemovedCourier && (
				<Notice
					status="success"
					isDismissible
					onRemove={() => setLastRemovedCourier(null)}
				>
					{`"${lastRemovedCourier}" ${__('removed from list.', 'parcel2go-shipping')}`}
				</Notice>
			)}
			<Dropdown
				popoverProps={{ placement: 'bottom-start' }}
				renderToggle={({ isOpen, onToggle }) => (
					<Button
						variant="secondary"
						icon={chevronDown}
						iconPosition="right"
						disabled={!canFetch || disabled}
						onClick={() => {
							if (!canFetch || disabled) return;
							onOpenDropdown();
								onToggle();
						}}
						aria-expanded={isOpen}
						aria-haspopup="listbox"
						style={{
							display: 'flex',
							justifyContent: 'space-between',
							alignItems: 'center',
							width: '100%',
						}}
					>
						{quotesLoading
							? __('Loading…', 'parcel2go-shipping')
							: __('Select default courier', 'parcel2go-shipping')}
					</Button>
				)}
				renderContent={({ onClose }) => {
					if (quotesLoading) {
						return (
							<Flex
								align="center"
								justify="start"
								wrap={false}
								gap={2}
								style={{ minWidth: 240, padding: '8px 12px' }}
							>
								<Spinner />
								<span>
									{__('Loading quotes…', 'parcel2go-shipping')}
								</span>
							</Flex>
						);
					}
					if (quotesError) {
						return (
							<div style={{ minWidth: 240 }}>
								<Notice status="error" isDismissible={false}>
									{quotesError}
								</Notice>
							</div>
						);
					}
					if (quotesList.length === 0) {
						return (
							<p
								style={{
									minWidth: 240,
									padding: '8px 12px',
									margin: 0,
								}}
							>
								{__('No quotes found.', 'parcel2go-shipping')}
							</p>
						);
					}
					return (
						<MenuGroup>
							{quotesList.map((quote, index) => {
								const service = quote.service;
								if (!service) return null;

								const displayName =
									service.courier && service.name
										? `${service.courier} – ${service.name}`
										: service.name ||
											service.courier ||
											service.slug ||
											'—';
								const logo = getCourierLogo(
									service.courierSlug,
									service.courier
								);
								const alreadyAdded = selectedCouriers.some(
									(selected) => selected.slug === service.slug
								);
								const uniqueKey = `${String(quote.id ?? '')}-${service.courierSlug ?? ''}-${service.slug ?? ''}-${index}`;
								return (
									<MenuItem
										key={uniqueKey}
										onClick={() => {
											if (!alreadyAdded && service) {
												onAddCourier(service);
												onClose();
											}
										}}
										disabled={alreadyAdded || disabled}
									>
										<Flex
											align="center"
											justify="start"
											wrap={false}
											gap={2}
										>
											{logo && (
												<img
													src={logo}
													alt=""
													width={24}
													height={24}
												/>
											)}
											<span>{displayName}</span>
											{alreadyAdded && (
												<span style={{ marginLeft: 'auto', color: '#757575' }}>✓</span>
											)}
										</Flex>
									</MenuItem>
								);
							})}
						</MenuGroup>
					);
				}}
			/>
			{selectedCouriers.length > 0 && (
				<>
			<Flex justify="space-between" align="center" gap={2} style={{ paddingTop: 12, borderBottom: '1px solid #e0e0e0'}}>
				<strong>
					{sprintf(
						/* translators: %d: number of selected services */
						__('Selected Services (%d).', 'parcel2go-shipping'),
						selectedCouriers.length
					)}
				</strong>
				{ clearAllButton && (
					<Button
						variant="tertiary"
						onClick={clearAllButton.onClick}
						disabled={clearAllButton.disabled}
						isBusy={clearAllButton.isBusy}
					>
						{clearAllButton.label}
					</Button>
				)}
			</Flex>
			<Flex gap={2} justify="flex-start" align="center" wrap>
				{selectedCouriers.map((service, index) => {
					const logo = getCourierLogo(
						service.courierSlug,
						service.courier
					);
					const displayName = service.courier || service.name;
					const pillKey = `${service.courier}-${service.courierSlug}-${index}`;
					
					return (
						<span key={pillKey} style={pillStyle('#e6e6e6', '#1e1e1e')}>
							{logo && (
								<img
									src={logo}
									alt={service.courier}
									width={16}
									height={16}
									style={{ marginRight: -2 }}
								/>
							)}
							<span>{displayName}</span>
							<button
								type="button"
								aria-label={__(
									'Remove courier',
									'parcel2go-shipping'
								)}
								onClick={() => handleRemoveCourier(service)}
								disabled={clearAllButton?.disabled}
								style={{
									border: 'none',
									background: 'transparent',
									cursor: clearAllButton?.disabled ? 'default' : 'pointer',
									padding: 0,
									lineHeight: 1,
									marginLeft: 4,
									opacity: clearAllButton?.disabled ? 0.5 : 1,
								}}
							>
								×
							</button>
						</span>
					);
				})}
			</Flex>
			</>
		)}
		</Flex>
	);
}

export default memo(CourierSelectWithListInner);
