'use client';

import { useEffect, useState } from 'react';
import dynamic from 'next/dynamic';
import { storeImageSrc } from '@/lib/storeImage';

const GeoMap = dynamic(() => import('../checkout/GeoMap'), { ssr: false });
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
import CancelRoundedIcon from '@mui/icons-material/CancelRounded';
import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';
import HourglassEmptyRoundedIcon from '@mui/icons-material/HourglassEmptyRounded';
import Inventory2RoundedIcon from '@mui/icons-material/Inventory2Rounded';
import LocalShippingRoundedIcon from '@mui/icons-material/LocalShippingRounded';
import PendingRoundedIcon from '@mui/icons-material/PendingRounded';
import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
import Alert from '@mui/material/Alert';
import Button from '@mui/material/Button';
import type { StoreConfig } from '../../config/defaultStoreConfig';
import {
	OrderBody,
	OrderCard,
	OrderDelivery,
	OrderItemsList,
	OrderItemsTable,
	OrderItemThumb,
	OrderMeta,
	OrderMetaItem,
	OrderStatusBanner,
	OrderStatusLabel,
	OrderTimeline,
	OrderTotals,
	SectionBackBtn,
	TrackingError,
	TrackingSearch,
	TrackingSearchRow,
	TrackingWrap,
} from './styles';

type OrderItem = {
	id?: string;
	name: string;
	sku?: string;
	quantity: number;
	unitPrice: number;
	lineTotal: number;
	imageUrl?: string;
	// legacy fallback
	price?: number;
	image?: string;
};

type OrderResult = {
	codigo: string;
	estado: string;
	paymentMethod: string;
	customer: { name?: string; email?: string; phone?: string };
	delivery: {
		address?: string;
		nroCasa?: string;
		ciudad?: string;
		distrito?: string;
		departamento?: string;
		lat?: number | null;
		lng?: number | null;
		type?: 'delivery' | 'pickup';
		methodId?: string;
		methodName?: string;
	};
	items: OrderItem[];
	totals: {
		subtotal: number;
		deliveryCost?: number;
		delivery?: number;
		total: number;
		paymentMethodName?: string;
	};
	createdAt: string;
	comentarios?: string | null;
	reanudarPagoUrl?: string | null;
	eventos?: {
		tipo: string;
		estadoAnterior: string | null;
		estadoNuevo: string | null;
		fecha: string;
	}[];
};

const STATUS_ICON: Record<string, React.ElementType> = {
	pendiente_pago: HourglassEmptyRoundedIcon,
	pago_confirmado: PendingRoundedIcon,
	en_verificacion: PendingRoundedIcon,
	verificado: CheckCircleRoundedIcon,
	preparando: Inventory2RoundedIcon,
	empaquetado: Inventory2RoundedIcon,
	listo_retiro: Inventory2RoundedIcon,
	listo_despacho: Inventory2RoundedIcon,
	en_camino: LocalShippingRoundedIcon,
	retirado: CheckCircleRoundedIcon,
	pagado: PendingRoundedIcon,
	en_preparacion: Inventory2RoundedIcon,
	enviado: LocalShippingRoundedIcon,
	entregado: CheckCircleRoundedIcon,
	cancelado: CancelRoundedIcon,
};

function formatGs(value: number) {
	return `Gs. ${Number(value).toLocaleString('es-PY')}`;
}

function formatDateTime(iso: string) {
	try {
		return new Date(iso).toLocaleString('es-PY', {
			day: '2-digit',
			month: 'short',
			hour: '2-digit',
			minute: '2-digit',
		});
	} catch {
		return iso;
	}
}

function formatDate(iso: string) {
	try {
		return new Date(iso).toLocaleDateString('es-PY', {
			day: '2-digit',
			month: 'short',
			year: 'numeric',
		});
	} catch {
		return iso;
	}
}

type Props = {
	config: StoreConfig;
	onClose: () => void;
	initialCode?: string;
};

/**
 * El medio que eligió el comprador ("Novasis Pay (tarjetas)", "Transferencia
 * bancaria"). Antes se mostraba el identificador interno con capitalize:
 * "Novasis_pay". Los pedidos viejos no guardaban el nombre: se cae a una etiqueta.
 */
export function nombreMedioPago(metodo: string | null | undefined, nombre?: string | null): string {
	if (nombre?.trim()) return nombre.trim();
	return metodo === 'novasis_pay' ? 'Novasis Pay' : 'Manual / transferencia';
}

export default function TrackingSection({ config, onClose, initialCode = '' }: Props) {
	const [query, setQuery] = useState(initialCode);
	const [loading, setLoading] = useState(false);
	const [order, setOrder] = useState<OrderResult | null>(null);
	const [error, setError] = useState<string | null>(null);

	const handleSearch = async (codigo: string = query) => {
		const code = codigo.trim();
		if (!code) return;
		setLoading(true);
		setError(null);
		setOrder(null);
		try {
			const res = await fetch(
				`/api/store/checkout/${encodeURIComponent(code)}?subdominio=${encodeURIComponent(config.identity.subdomain)}`,
			);
			if (res.status === 404) {
				setError('No se encontró ningún pedido con ese código. Verificá el código e intentá de nuevo.');
				return;
			}
			if (!res.ok) throw new Error('Error al consultar el pedido');
			const data = (await res.json()) as OrderResult;
			setOrder(data);
			if (data.codigo) setQuery(data.codigo);
		} catch {
			setError('No se pudo conectar con el servidor. Intentá nuevamente.');
		} finally {
			setLoading(false);
		}
	};

	// El link de seguimiento que comparte el panel (y el retorno de Novasis Pay)
	// trae el código: antes quedaba cargado en el buscador y el cliente tenía que
	// tocar "Buscar" para ver su propio pedido.
	useEffect(() => {
		if (initialCode.trim()) handleSearch(initialCode);
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [initialCode]);

	const deliveryCost = order ? (order.totals.deliveryCost ?? order.totals.delivery ?? 0) : 0;
	const StatusIcon = order ? (STATUS_ICON[order.estado] ?? PendingRoundedIcon) : null;

	return (
		<TrackingWrap>
			<div>
				<SectionBackBtn type="button" onClick={onClose}>
					<ArrowBackRoundedIcon fontSize="small" />
					Volver
				</SectionBackBtn>
			</div>

			<TrackingSearch>
				<h2>Rastrear pedido</h2>
				<p>Ingresá tu código de pedido para ver el estado de tu compra.</p>
				<TrackingSearchRow>
					<input
						type="text"
						placeholder="Ej: ECO-2025-0001"
						value={query}
						onChange={(e) => setQuery(e.target.value)}
						onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
						autoFocus
					/>
					<button type="button" onClick={() => handleSearch()} disabled={loading || !query.trim()}>
						<SearchRoundedIcon fontSize="small" />
						{loading ? 'Buscando…' : 'Buscar'}
					</button>
				</TrackingSearchRow>
				{error && <TrackingError>{error}</TrackingError>}
			</TrackingSearch>

			{order && StatusIcon && (
				<OrderCard>
					<OrderStatusBanner $estado={order.estado}>
						<StatusIcon />
						{OrderStatusLabel[order.estado] ?? order.estado}
					</OrderStatusBanner>

					<OrderBody>
						{/* Cancelar en el gateway no borra el pedido: en vez de mandarlo a rehacer
						    el checkout (y duplicarlo), se le ofrece retomar el mismo pago. */}
						{order.reanudarPagoUrl && (
							<Alert
								severity="warning"
								variant="outlined"
								sx={{ borderRadius: 2.5, mb: 0.5 }}
								action={
									<Button
										size="small"
										variant="contained"
										href={order.reanudarPagoUrl}
										sx={{ fontWeight: 700, whiteSpace: 'nowrap' }}
									>
										Retomar el pago
									</Button>
								}
							>
								Este pedido está esperando el pago.
							</Alert>
						)}
						<OrderMeta>
							<OrderMetaItem>
								<label>Código de pedido</label>
								<span>{order.codigo}</span>
							</OrderMetaItem>
							<OrderMetaItem>
								<label>Fecha</label>
								<span>{formatDate(order.createdAt)}</span>
							</OrderMetaItem>
							<OrderMetaItem>
								<label>Método de pago</label>
								<span>{nombreMedioPago(order.paymentMethod, order.totals.paymentMethodName)}</span>
							</OrderMetaItem>
							{order.customer.name && (
								<OrderMetaItem>
									<label>Cliente</label>
									<span>{order.customer.name}</span>
								</OrderMetaItem>
							)}
						</OrderMeta>

						<OrderItemsList>
							<h4>Productos ({order.items.length})</h4>
							<OrderItemsTable>
								<thead>
									<tr>
										<th style={{ width: 56, paddingLeft: 0 }} />
										<th>Producto</th>
										<th style={{ textAlign: 'center' }}>Cant.</th>
										<th className="num">P. Unit.</th>
										<th className="num">Subtotal</th>
									</tr>
								</thead>
								<tbody>
									{order.items.map((item, i) => {
										const unitPrice = item.unitPrice ?? item.price ?? 0;
										const lineTotal = item.lineTotal ?? unitPrice * item.quantity;
										const imgSrc = item.imageUrl || item.image;
										return (
											<tr key={i}>
												<td className="img-cell">
													<OrderItemThumb>
														<img src={storeImageSrc(imgSrc, item.name)} alt={item.name} />
													</OrderItemThumb>
												</td>
												<td className="name-cell">
													{item.name}
													{item.sku && (
														<span
															style={{
																display: 'block',
																fontSize: 11,
																fontWeight: 600,
																color: 'var(--store-muted)',
															}}
														>
															Cód. {item.sku}
														</span>
													)}
												</td>
												<td className="qty-cell">× {item.quantity}</td>
												<td className="unit-cell">{formatGs(unitPrice)}</td>
												<td className="subtotal-cell">{formatGs(lineTotal)}</td>
											</tr>
										);
									})}
								</tbody>
							</OrderItemsTable>
						</OrderItemsList>

						{(order.delivery.address || order.delivery.ciudad) && (
							<OrderDelivery>
								<h4>{order.delivery.type === 'pickup' ? 'Retiro en local' : 'Dirección de entrega'}</h4>
								{/* El checkout guarda nro de casa, distrito y coordenadas; antes se mostraba
								    solo calle/ciudad/departamento y el resto quedaba invisible. */}
								<p>
									{[
										order.delivery.address,
										order.delivery.nroCasa && order.delivery.nroCasa !== '0'
											? `Nro. ${order.delivery.nroCasa}`
											: null,
										order.delivery.distrito,
										order.delivery.ciudad,
										order.delivery.departamento,
									]
										.filter(Boolean)
										.join(', ')}
								</p>
								{order.delivery.methodName && (
									<p style={{ marginTop: 4, fontWeight: 600, color: 'var(--store-muted)', fontSize: 12 }}>
										{order.delivery.methodName}
									</p>
								)}
								{order.delivery.lat != null && order.delivery.lng != null && (
									<div style={{ display: 'grid', gap: 6, marginTop: 8 }}>
										<GeoMap lat={Number(order.delivery.lat)} lng={Number(order.delivery.lng)} height={180} readOnly />
										<a
											href={`https://www.google.com/maps/search/?api=1&query=${order.delivery.lat},${order.delivery.lng}`}
											target="_blank"
											rel="noreferrer"
											style={{ justifySelf: 'start', background: 'transparent', fontSize: 12, fontWeight: 700, color: 'var(--store-primary)' }}
										>
											Abrir en Google Maps
										</a>
									</div>
								)}
							</OrderDelivery>
						)}

						{order.comentarios && (
							<OrderDelivery>
								<h4>Tus indicaciones</h4>
								<p style={{ fontWeight: 500, whiteSpace: 'pre-wrap' }}>{order.comentarios}</p>
							</OrderDelivery>
						)}

						{!!order.eventos?.length && (
							<OrderTimeline>
								<h4>Historial del pedido</h4>
								<ol>
									{order.eventos.map((ev, i) => (
										<li key={i}>
											<strong>
												{ev.tipo === 'creacion'
													? 'Pedido recibido'
													: ev.tipo === 'incidencia'
														? 'Incidencia registrada'
														: (ev.estadoNuevo && OrderStatusLabel[ev.estadoNuevo]) ??
															ev.estadoNuevo ??
															'Actualización'}
											</strong>
											<span>{formatDateTime(ev.fecha)}</span>
										</li>
									))}
								</ol>
							</OrderTimeline>
						)}

						<OrderTotals>
							<div className="row">
								<span>Subtotal</span>
								<span>{formatGs(order.totals.subtotal)}</span>
							</div>
							{deliveryCost > 0 && (
								<div className="row">
									<span>Envío</span>
									<span>{formatGs(deliveryCost)}</span>
								</div>
							)}
							<div className="row total">
								<span>Total</span>
								<span>{formatGs(order.totals.total)}</span>
							</div>
						</OrderTotals>
					</OrderBody>
				</OrderCard>
			)}
		</TrackingWrap>
	);
}
