import { Section, SectionHeader, Spinner } from '@woocommerce/components';
import { __ } from '@wordpress/i18n';
import {
	useState,
	useCallback,
	useMemo,
	Suspense,
	useEffect,
	useRef,
} from '@wordpress/element';
import {
	Button,
	Card,
	CardBody,
	Flex,
	Icon,
	Notice,
} from '@wordpress/components';
import { LazyBookingPrereqsNotice } from '../shared/components';
import { update, shipping, comment, help, settings as settingsIcon } from '@wordpress/icons';
import {
	WelcomeCard,
	ActionCard,
	FeedbackModal,
	LandingDashboardCards,
	OrderTable,
	OnboardingCard,
} from '../features/orders';
import {
	getSettingsPageUrl,
	getPluginSettingsPageUrl,
	getShipmentsPageUrl,
	validateAddresses,
} from '../shared/utils';
import {
	useWindowSize,
	useOrders,
	useSettings,
	useParcel2goAuth,
	usePrepay,
} from '../shared/hooks';
import BulkShip from '../features/orders/bulk-ship';
import { PrePayBalance } from '../types';

const ROWS_PER_PAGE = 20;

interface LandingPageProps {
	onShipNow: (orderId: number) => void;
}

const LandingPage = ({ onShipNow }: LandingPageProps) => {
	const { orders, total, page, loading, error, fetchOrders } =
		useOrders(ROWS_PER_PAGE);
	const {
		startLogin,
		isLoading,
		isLinked,
		error: loginError,
	} = useParcel2goAuth();
	const {
		settings,
		saveOnboardingSettings,
		refetch: refetchSettings,
		loading: settingsLoading
	} = useSettings();
	const {
		fetchBalance,
		makePrepayPayment,
		createTopUp,
		isPrepayLoading,
		prepayError,
	} = usePrepay();
	const [prepayBalance, setPrepayBalance] = useState<PrePayBalance | null>(
		null
	);
	const [isFeedbackModalOpen, setIsFeedbackModalOpen] = useState(false);
	const [selectedOrderIds, setSelectedOrderIds] = useState<number[]>([]);
	const onboardingSyncStepRef = useRef<number | null>(null);

	useEffect(() => {
		if (!isLinked) return;
		let cancelled = false;

		fetchBalance().then((balance) => {
			if (!cancelled && balance) setPrepayBalance(balance);
		});

		return () => {
			cancelled = true;
		};
	}, [fetchBalance, isLinked]);

	const store = useMemo(() => {
		return settings?.shipping ?? null;
	}, [settings]);

	const handlePageChange = useCallback(
		(newPage: number) => {
			fetchOrders(newPage);
		},
		[fetchOrders]
	);

	const handleRefresh = useCallback(() => {
		fetchOrders(page);
		refetchSettings();
	}, [fetchOrders, page, refetchSettings]);

	const handleGiveFeedback = useCallback(() => {
		setIsFeedbackModalOpen(true);
	}, []);

	const handleSelectionChange = useCallback((ids: number[]) => {
		setSelectedOrderIds(ids);
	}, []);

	const addressValidation = useMemo(
		() => validateAddresses(store, null),
		[store]
	);

	const handleDismissOnboarding = useCallback(() => {
		void saveOnboardingSettings({
			onboarding: {
				dismissed: true,
				currentStep: settings?.onboarding?.currentStep ?? 1,
			},
		});
	}, [saveOnboardingSettings, settings?.onboarding?.currentStep]);

	const handleSkipOnboardingStep = useCallback(
		(step: number) => {
			const nextStep = Math.min(step + 1, 3);
			void saveOnboardingSettings({
				onboarding: {
					dismissed: false,
					currentStep: nextStep,
				},
			});
		},
		[saveOnboardingSettings]
	);

	const hasDefaultServiceSettings = useMemo(() => {
		return Object.keys(settings?.defaultServiceCouriers || {}).length > 0;
	}, [settings?.defaultServiceCouriers]);

	useEffect(() => {
		if (!settings) return;

		const persistedStep = settings.onboarding?.currentStep ?? 1;
		const derivedStep = hasDefaultServiceSettings ? 3 : isLinked ? 2 : 1;

		if (persistedStep >= derivedStep) {
			onboardingSyncStepRef.current = null;
			return;
		}

		if (onboardingSyncStepRef.current === derivedStep) {
			return;
		}

		onboardingSyncStepRef.current = derivedStep;

		void saveOnboardingSettings({
			onboarding: {
				dismissed: settings.onboarding?.dismissed ?? false,
				currentStep: derivedStep,
			},
		}).catch(() => {
			onboardingSyncStepRef.current = null;
		});
	}, [hasDefaultServiceSettings, isLinked, saveOnboardingSettings, settings]);

	const showOnboarding = settings && !settings.onboarding?.dismissed;

	// Auto-select orders without bulkError when orders load
	useEffect(() => {
		if (loading || !Array.isArray(orders)) return;

		const selectableOrderIds = orders
			.filter((order) => !order.bulkError)
			.map((order) => order.id);

		setSelectedOrderIds(selectableOrderIds);
	}, [loading, orders]);

	const refetchBalance = useCallback(async () => {
		if (!isLinked) return;
		const balance = await fetchBalance();
		if (balance) setPrepayBalance(balance);
	}, [fetchBalance, isLinked]);

	return (
		<Section component="article">
			<WelcomeCard
				startLogin={startLogin}
				isLoading={isLoading}
				isLinked={isLinked}
				error={loginError}
			/>
			{showOnboarding && (
				<OnboardingCard
					isConnected={isLinked}
					isLoading={settingsLoading}
					currentStep={settings?.onboarding?.currentStep ?? 1}
					loginLoading={isLoading}
					onLinkAccount={startLogin}
					onDismiss={handleDismissOnboarding}
					onSkipStep={handleSkipOnboardingStep}
					hasDefaultServiceSettings={hasDefaultServiceSettings}
				/>
			)}
			{!loading && !addressValidation.valid && (
				<div style={{ marginBottom: 16 }}>
					<Suspense fallback={null}>
						<LazyBookingPrereqsNotice
							storeMissing={addressValidation.storeMissing}
							customerMissing={addressValidation.customerMissing}
							orderHasWeight={true}
							orderId={null}
							settingsUrl={
								isLinked
									? getPluginSettingsPageUrl()
									: getSettingsPageUrl()
							}
						/>
					</Suspense>
				</div>
			)}
			{isLinked && (
				<LandingDashboardCards
					prepayBalance={prepayBalance}
					isBalanceLoading={isPrepayLoading}
					prepayError={prepayError}
					refetchBalance={refetchBalance}
					createTopUp={createTopUp}
				/>
			)}
			<SectionHeader
				title={__('Orders Ready to Ship', 'parcel2go-shipping')}
			/>
			{loading && (
				<Flex
					justify="center"
					align="center"
					style={{ minHeight: 120, padding: 24 }}
				>
					<Spinner />
				</Flex>
			)}
			{error && (
				<Flex
					justify="center"
					align="center"
					style={{ minHeight: 120, padding: 24 }}
				>
					<Notice status="error">{error}</Notice>
				</Flex>
			)}
			{!loading &&
				!error &&
				Array.isArray(orders) &&
				(orders.length || total > 0 ? (
					<OrderTable
						orders={orders}
						settings={settings}
						total={total}
						page={page}
						rowsPerPage={ROWS_PER_PAGE}
						onShipNow={onShipNow}
						onPageChange={handlePageChange}
						selectedOrderIds={selectedOrderIds}
						onSelectionChange={handleSelectionChange}
						onRefreshOrders={handleRefresh}
					/>
				) : (
					<Card>
						<CardBody>
							<Flex
								direction="column"
								align="center"
								justify="center"
								gap={3}
								style={{ padding: '48px 24px' }}
							>
								<Icon
									icon={shipping}
									size={48}
									style={{ fill: '#949494' }}
								/>
								<h3
									style={{
										margin: 0,
										fontSize: 16,
										fontWeight: 600,
									}}
								>
									{__(
										'No orders ready to ship',
										'parcel2go-shipping'
									)}
								</h3>
								<p
									style={{
										margin: 0,
										color: '#757575',
										textAlign: 'center',
										maxWidth: 400,
									}}
								>
									{__(
										'When customers place orders with a "Processing" status, they\'ll appear here ready for you to book shipping.',
										'parcel2go-shipping'
									)}
								</p>
							</Flex>
						</CardBody>
					</Card>
				))}
			<CardBody style={{ marginTop: 24, background: '#fff' }}>
				<Flex
					gap={3}
					align="center"
					justify={
						isLinked && selectedOrderIds.length > 0
							? 'space-between'
							: 'flex-start'
					}
				>
					<Button
						variant="secondary"
						onClick={handleRefresh}
						disabled={loading}
						isBusy={loading}
						icon={loading ? undefined : update}
					>
						{loading
							? __('Refreshing…', 'parcel2go-shipping')
							: __('Refresh orders', 'parcel2go-shipping')}
					</Button>
					{isLinked && selectedOrderIds.length > 0 && (
						<BulkShip
							prepayError={prepayError}
							isBalanceLoading={isPrepayLoading}
							fetchBalance={refetchBalance}
							makePrepayPayment={makePrepayPayment}
							createTopUp={createTopUp}
							prepayBalance={prepayBalance}
							selectedOrders={orders.filter((order) =>
								selectedOrderIds.includes(order.id)
							)}
							settings={settings}
							isLinked={isLinked}
							onComplete={() => {
								setSelectedOrderIds([]);
								fetchBalance();
								handleRefresh();
							}}
						/>
					)}
				</Flex>
			</CardBody>
			<div style={{ marginTop: 32 }}>
				{!isLinked && (
					<div style={{display:'grid', gap: '12px', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))'}}>
						<ActionCard
							icon={shipping}
							title={__(
								'Previous shipping labels',
								'parcel2go-shipping'
							)}
							description={__(
								'Get tracking and help with your orders.',
								'parcel2go-shipping'
							)}
							buttonLabel={__(
								'View previous shipments',
								'parcel2go-shipping'
							)}
							onButtonClick={() =>
								window.location.assign(getShipmentsPageUrl())
							}
						/>

						<ActionCard
							icon={settingsIcon}
							title={__(
								'Parcel2Go Settings',
								'parcel2go-shipping'
							)}
							description={__(
								'Set your default shipping rules for faster checkout.',
								'parcel2go-shipping'
							)}
							buttonLabel={__('Settings', 'parcel2go-shipping')}
							onButtonClick={() => window.location.assign(getPluginSettingsPageUrl())}
						/>
					</div>
				)}
				<ActionCard
					icon={comment}
					title={__('Help us improve!', 'parcel2go-shipping')}
					description={__(
						'Share your thoughts about features, setup, or anything that could be better.',
						'parcel2go-shipping'
					)}
					buttonLabel={__('Give Feedback', 'parcel2go-shipping')}
					onButtonClick={handleGiveFeedback}
				/>
			</div>
			<FeedbackModal
				isOpen={isFeedbackModalOpen}
				onRequestClose={() => setIsFeedbackModalOpen(false)}
			/>
			<ActionCard
				icon={help}
				title={__('How to contact Parcel2Go?', 'parcel2go-shipping')}
				description={__(
					'If you need help, we offer a number of options for customer support. You can contact us on live chat, our agents are available 7 days a week, 24 hours a day.',
					'parcel2go-shipping'
				)}
				buttonLabel={__('Contact Us', 'parcel2go-shipping')}
				onButtonClick={() => {
					window.open(
						'https://www.parcel2go.com/help-centre/parcels/question/general/how-do-i-contact-parcel2go',
						'_blank'
					);
				}}
			/>
		</Section>
	);
};

export default LandingPage;
