'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import CircularProgress from '@mui/material/CircularProgress';
import InputAdornment from '@mui/material/InputAdornment';
import TextField from '@mui/material/TextField';
import ArrowForwardRoundedIcon from '@mui/icons-material/ArrowForwardRounded';
import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
import { styled } from '@mui/material/styles';
import type { Product } from '../../config/defaultStoreConfig';
import { SearchWrap } from './styles';
import { storeImageSrc } from '@/lib/storeImage';
import {
	emptyStoreSearch,
	fetchStoreSearch,
	searchResponseProducts,
	type StoreSearchResponse
} from '@/lib/storeSearch';

const MIN_CHARS = 3;

// ── Dropdown styles ───────────────────────────────────────────────────────────

const SearchOuter = styled('div')({
	position: 'relative',
	minWidth: 0,
	flex: 1
});

const SearchAction = styled('button')({
	width: 34,
	height: 34,
	display: 'inline-flex',
	alignItems: 'center',
	justifyContent: 'center',
	border: 0,
	borderRadius: 8,
	background: 'var(--store-primary)',
	color: '#fff',
	cursor: 'pointer',
	boxShadow: '0 8px 18px color-mix(in srgb, var(--store-primary) 25%, transparent)',
	transition: 'transform 180ms ease, box-shadow 180ms ease, background 180ms ease',
	'&:hover': {
		transform: 'translateX(2px)',
		background: 'color-mix(in srgb, var(--store-primary) 82%, var(--store-secondary))',
		boxShadow: '0 10px 22px color-mix(in srgb, var(--store-primary) 34%, transparent)'
	},
	'&:focus-visible': {
		outline: '3px solid color-mix(in srgb, var(--store-accent) 40%, transparent)',
		outlineOffset: 2
	},
	'& svg': { fontSize: 18 }
});

const Dropdown = styled('div')({
	position: 'absolute',
	top: 'calc(100% + 6px)',
	left: 0,
	right: 0,
	zIndex: 1400,
	background: '#fff',
	borderRadius: 12,
	boxShadow: '0 24px 60px rgba(15, 23, 42, 0.14)',
	border: '1px solid rgba(20, 33, 31, 0.08)',
	overflow: 'hidden'
});

const ResultItem = styled('button', {
	shouldForwardProp: (p) => p !== 'active'
})<{ active: boolean }>(({ active }) => ({
	display: 'grid',
	gridTemplateColumns: '44px 1fr auto',
	alignItems: 'center',
	gap: 12,
	width: '100%',
	padding: '10px 14px',
	border: 0,
	background: active ? 'color-mix(in srgb, var(--store-primary) 6%, #ffffff)' : 'transparent',
	cursor: 'pointer',
	textAlign: 'left',
	transition: 'background 120ms ease',
	'&:hover': {
		background: 'color-mix(in srgb, var(--store-primary) 6%, #ffffff)'
	},
	'& + &': {
		borderTop: '1px solid rgba(20, 33, 31, 0.05)'
	}
}));

const ResultThumb = styled('img')({
	width: 44,
	height: 44,
	borderRadius: 8,
	objectFit: 'contain',
	background: '#f7f8f9',
	border: '1px solid rgba(20, 33, 31, 0.06)',
	display: 'block',
	flexShrink: 0
});

const ResultBody = styled('div')({
	minWidth: 0,
	'& > strong': {
		display: 'block',
		fontSize: 14,
		fontWeight: 700,
		color: 'var(--store-text)',
		overflow: 'hidden',
		textOverflow: 'ellipsis',
		whiteSpace: 'nowrap'
	},
	'& > small': {
		display: 'block',
		marginTop: 2,
		fontSize: 12,
		color: 'var(--store-muted)'
	}
});

const ResultPrice = styled('span')({
	fontSize: 14,
	fontWeight: 900,
	color: 'var(--store-primary)',
	whiteSpace: 'nowrap',
	flexShrink: 0
});

const ViewAllRow = styled('button')({
	display: 'flex',
	alignItems: 'center',
	justifyContent: 'center',
	gap: 6,
	width: '100%',
	padding: '10px 14px',
	border: 0,
	borderTop: '1px solid rgba(20, 33, 31, 0.08)',
	background: 'color-mix(in srgb, var(--store-primary) 4%, #ffffff)',
	color: 'var(--store-primary)',
	fontSize: 13,
	fontWeight: 900,
	cursor: 'pointer',
	transition: 'background 120ms ease',
	'&:hover': {
		background: 'color-mix(in srgb, var(--store-primary) 10%, #ffffff)'
	},
	'& svg': { fontSize: 15 }
});

const EmptyRow = styled('div')({
	padding: '14px 16px',
	fontSize: 13,
	color: 'var(--store-muted)',
	textAlign: 'center'
});

const Hint = styled('div')({
	padding: '8px 14px',
	fontSize: 11,
	fontWeight: 850,
	color: 'var(--store-muted)',
	textTransform: 'uppercase',
	letterSpacing: 1,
	borderBottom: '1px solid rgba(20, 33, 31, 0.06)'
});

const SearchNotice = styled('div')({
	padding: '10px 14px',
	borderBottom: '1px solid rgba(20, 33, 31, 0.06)',
	background: 'color-mix(in srgb, var(--store-accent) 10%, #ffffff)',
	color: 'var(--store-text)',
	fontSize: 12,
	fontWeight: 750,
	'& button': {
		padding: 0,
		border: 0,
		background: 'transparent',
		color: 'var(--store-primary)',
		font: 'inherit',
		fontWeight: 950,
		textDecoration: 'underline',
		cursor: 'pointer'
	}
});

// ── Component ─────────────────────────────────────────────────────────────────

interface Props {
	query: string;
	formatPrice: (value: number) => string;
	onQueryChange: (value: string) => void;
	onOpenDetail: (product: Product) => void;
}

export default function StoreSearchBar({ query, formatPrice, onQueryChange, onOpenDetail }: Props) {
	const [inputValue, setInputValue] = useState(query);
	const [response, setResponse] = useState<StoreSearchResponse>(() => emptyStoreSearch(query));
	const [open, setOpen] = useState(false);
	const [loading, setLoading] = useState(false);
	const [activeIndex, setActiveIndex] = useState(-1);
	const outerRef = useRef<HTMLDivElement>(null);
	const debounceRef = useRef<ReturnType<typeof setTimeout>>(undefined);
	const requestRef = useRef<AbortController>(undefined);
	const results = searchResponseProducts(response);

	// Sync when external query is cleared (e.g. reset)
	useEffect(() => setInputValue(query), [query]);

	const fetchResults = useCallback(async (term: string) => {
		requestRef.current?.abort();
		const controller = new AbortController();
		requestRef.current = controller;
		setLoading(true);
		try {
			const data = await fetchStoreSearch(term, 8, controller.signal);
			setResponse(data);
			setOpen(true);
		} catch (error) {
			if ((error as Error).name !== 'AbortError') setResponse(emptyStoreSearch(term));
		} finally {
			if (requestRef.current === controller) setLoading(false);
		}
	}, []);

	const handleChange = (value: string) => {
		setInputValue(value);
		setActiveIndex(-1);
		clearTimeout(debounceRef.current);

		if (value.trim().length < MIN_CHARS) {
			requestRef.current?.abort();
			setResponse(emptyStoreSearch(value));
			setOpen(false);
			return;
		}

		debounceRef.current = setTimeout(() => fetchResults(value), 320);
	};

	useEffect(
		() => () => {
			clearTimeout(debounceRef.current);
			requestRef.current?.abort();
		},
		[]
	);

	const commitSearch = useCallback(
		(value: string) => {
			setOpen(false);
			onQueryChange(value);
		},
		[onQueryChange]
	);

	const selectProduct = useCallback(
		(product: Product) => {
			setOpen(false);
			setInputValue('');
			onOpenDetail(product);
		},
		[onOpenDetail]
	);

	const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
		if (e.key === 'ArrowDown') {
			e.preventDefault();
			setActiveIndex((i) => Math.min(i + 1, results.length - 1));
		} else if (e.key === 'ArrowUp') {
			e.preventDefault();
			setActiveIndex((i) => Math.max(i - 1, -1));
		} else if (e.key === 'Enter') {
			if (activeIndex >= 0 && results[activeIndex]) {
				selectProduct(results[activeIndex]);
			} else {
				commitSearch(inputValue);
			}
		} else if (e.key === 'Escape') {
			setOpen(false);
		}
	};

	// Click outside closes dropdown
	useEffect(() => {
		const handler = (e: MouseEvent) => {
			if (outerRef.current && !outerRef.current.contains(e.target as Node)) {
				setOpen(false);
			}
		};
		document.addEventListener('mousedown', handler);
		return () => document.removeEventListener('mousedown', handler);
	}, []);

	const showDropdown = open && inputValue.trim().length >= MIN_CHARS;
	const applySuggestion = (suggestion: string) => {
		setInputValue(suggestion);
		commitSearch(suggestion);
	};

	return (
		<SearchOuter
			ref={outerRef}
			data-header-search="true"
		>
			<SearchWrap>
				<TextField
					fullWidth
					size="small"
					value={inputValue}
					placeholder="Buscar productos, marcas o categorías"
					onChange={(e) => handleChange(e.target.value)}
					onKeyDown={handleKeyDown}
					onFocus={() => {
						if (results.length > 0) setOpen(true);
					}}
					InputProps={{
						startAdornment: (
							<InputAdornment position="start">
								{loading ? (
									<CircularProgress
										size={16}
										sx={{ color: 'var(--store-primary)' }}
									/>
								) : (
									<SearchRoundedIcon fontSize="small" />
								)}
							</InputAdornment>
						),
						endAdornment: (
							<InputAdornment position="end">
								<SearchAction
									type="button"
									aria-label="Buscar"
									onClick={() => commitSearch(inputValue)}
								>
									<ArrowForwardRoundedIcon />
								</SearchAction>
							</InputAdornment>
						)
					}}
				/>
			</SearchWrap>

			{showDropdown && (
				<Dropdown role="listbox">
					<Hint>
						{response.matchType === 'fuzzy' || response.matchType === 'alternative'
							? `Productos similares (${results.length})`
							: `Resultados (${results.length})`}
					</Hint>

					{response.unavailableProductName && (
						<SearchNotice>
							<strong>{response.unavailableProductName}</strong> no está disponible. Te mostramos alternativas.
						</SearchNotice>
					)}

					{response.matchType === 'fuzzy' && response.suggestedQuery && (
						<SearchNotice>
							¿Quisiste decir{' '}
							<button
								type="button"
								onMouseDown={(event) => {
									event.preventDefault();
									applySuggestion(response.suggestedQuery!);
								}}
							>
								{response.suggestedQuery}
							</button>
							?
						</SearchNotice>
					)}

					{results.length === 0 && !loading && (
						<EmptyRow>Sin resultados para &quot;{inputValue}&quot;</EmptyRow>
					)}

					{results.map((product, i) => (
						<ResultItem
							key={product.id}
							type="button"
							role="option"
							active={i === activeIndex}
							aria-selected={i === activeIndex}
							onMouseEnter={() => setActiveIndex(i)}
							onMouseDown={(e) => {
								e.preventDefault();
								selectProduct(product);
							}}
						>
							<ResultThumb
								src={storeImageSrc(product.image, product.name)}
								alt={product.name}
							/>
							<ResultBody>
								<strong>{product.name}</strong>
								<small>
									{product.brand} · {product.category}
								</small>
							</ResultBody>
							<ResultPrice>{formatPrice(product.price)}</ResultPrice>
						</ResultItem>
					))}

					{results.length > 0 && (
						<ViewAllRow
							type="button"
							onMouseDown={(e) => {
								e.preventDefault();
								commitSearch(inputValue);
							}}
						>
							Ver todos {response.total || results.length} resultados para &quot;{inputValue}&quot;
							<ArrowForwardRoundedIcon />
						</ViewAllRow>
					)}
				</Dropdown>
			)}
		</SearchOuter>
	);
}
