'use client';

import '@/app/styles/header-search.scss';
import '@/app/styles/stock-common.scss';
import Styles from '../styles/layout.module.scss';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { fetchApi } from '@/lib/utils/client';
import { StockSuggestItem, StockSuggestResponse } from '@/types/stock';

const DEBOUNCE_MS = 300;
const LISTBOX_ID = 'header-suggest-listbox';

// 헤더 중앙 통합 검색 — 디바운스 suggest + combobox 키보드 탐색 (↑↓ Enter Esc), 선택 시 /stock/{code} 이동
export default function HeaderSearch()
{
	const router = useRouter();
	const boxRef = useRef<HTMLDivElement>(null);
	const inputRef = useRef<HTMLInputElement>(null);
	const debounceRef = useRef<ReturnType<typeof setTimeout>|null>(null);
	const requestSeq = useRef(0);

	const [keyword, setKeyword] = useState('');
	const [items, setItems] = useState<StockSuggestItem[]>([]);
	const [open, setOpen] = useState(false);
	const [activeIndex, setActiveIndex] = useState(-1);

	// 인라인 검색 포커스 단축키: '/' (finviz 관례). Ctrl+K(⌘K)는 커맨드 팔레트(SearchCommand)가 소유.
	useEffect(() => {
		const handler = (e: KeyboardEvent) => {
			if (e.key === '/' && !e.ctrlKey && !e.metaKey && !e.altKey) {
				const target = e.target as HTMLElement|null;
				const tag = target?.tagName;
				if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target?.isContentEditable) {
					return;
				}

				e.preventDefault();
				inputRef.current?.focus();
			}
		};

		window.addEventListener('keydown', handler);
		return () => {
			window.removeEventListener('keydown', handler);
		};
	}, []);

	// 외부 클릭 시 드롭다운 닫기
	useEffect(() => {
		const handler = (e: MouseEvent) => {
			if (boxRef.current && !boxRef.current.contains(e.target as Node)) {
				setOpen(false);
			}
		};

		document.addEventListener('mousedown', handler);
		return () => {
			document.removeEventListener('mousedown', handler);
		};
	}, []);

	useEffect(() => {
		return () => {
			if (debounceRef.current) {
				clearTimeout(debounceRef.current);
			}
		};
	}, []);

	const requestSuggest = useCallback(async (q: string) => {
		const seq = ++requestSeq.current;
		const res = await fetchApi<StockSuggestResponse>(`/api/stocks/suggest?q=${encodeURIComponent(q)}`, { silent: true });

		// 늦게 도착한 이전 응답 무시 (out-of-order 방지)
		if (seq !== requestSeq.current) {
			return;
		}

		setItems(res.success ? (res.data?.list ?? []) : []);
		setActiveIndex(-1);
		setOpen(true);
	}, []);

	// 입력 디바운스 300ms → suggest API
	const handleChange = useCallback((value: string) => {
		setKeyword(value);
		setActiveIndex(-1);

		if (debounceRef.current) {
			clearTimeout(debounceRef.current);
		}

		const trimmed = value.trim();
		if (!trimmed) {
			requestSeq.current++;
			setItems([]);
			setOpen(false);
			return;
		}

		debounceRef.current = setTimeout(() => {
			requestSuggest(trimmed);
		}, DEBOUNCE_MS);
	}, [requestSuggest]);

	const moveTo = useCallback((item: StockSuggestItem) => {
		setOpen(false);
		setKeyword('');
		setItems([]);
		setActiveIndex(-1);
		inputRef.current?.blur();
		router.push(`/stock/${item.code}`);
	}, [router]);

	const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
		// 한글 IME 조합 중 Enter 오동작 방지
		if (e.nativeEvent.isComposing) {
			return;
		}

		if (e.key === 'ArrowDown') {
			if (open && items.length > 0) {
				e.preventDefault();
				setActiveIndex(prev => (prev + 1) % items.length);
			}
			return;
		}

		if (e.key === 'ArrowUp') {
			if (open && items.length > 0) {
				e.preventDefault();
				setActiveIndex(prev => (prev <= 0 ? items.length - 1 : prev - 1));
			}
			return;
		}

		if (e.key === 'Enter') {
			e.preventDefault();

			if (open && activeIndex >= 0 && activeIndex < items.length) {
				moveTo(items[activeIndex]);
				return;
			}

			// 선택 없이 Enter — 종목 목록 검색으로 이동
			const trimmed = keyword.trim();
			if (trimmed) {
				setOpen(false);
				router.push(`/stock?q=${encodeURIComponent(trimmed)}`);
			}
			return;
		}

		if (e.key === 'Escape') {
			setOpen(false);
			setActiveIndex(-1);
		}
	}, [open, items, activeIndex, keyword, moveTo, router]);

	return (
		<div className={Styles.searchBox} role='search' ref={boxRef}>
			<input
				ref={inputRef}
				type='search'
				className={Styles.searchInput}
				placeholder='종목·글·유저 검색'
				aria-label='통합 검색'
				autoComplete='off'
				role='combobox'
				aria-expanded={open}
				aria-controls={LISTBOX_ID}
				aria-autocomplete='list'
				aria-activedescendant={activeIndex >= 0 ? `${LISTBOX_ID}-${activeIndex}` : undefined}
				value={keyword}
				onChange={e => handleChange(e.target.value)}
				onKeyDown={handleKeyDown}
				onFocus={() => {
					if (items.length > 0 && keyword.trim()) {
						setOpen(true);
					}
				}}
			/>
			<kbd className={Styles.searchKbd} aria-hidden='true'>Ctrl K</kbd>

			{open && (
				<ul id={LISTBOX_ID} className='header-suggest' role='listbox' aria-label='종목 자동완성'>
					{items.length === 0 ? (
						<li className='header-suggest__empty' role='presentation'>검색 결과가 없습니다.</li>
					) : (
						items.map((item, index) => (
							<li
								key={item.code}
								id={`${LISTBOX_ID}-${index}`}
								role='option'
								aria-selected={index === activeIndex}
								className={`header-suggest__item${index === activeIndex ? ' header-suggest__item--active' : ''}`}
								onMouseDown={e => {
									// blur 로 드롭다운이 먼저 닫히지 않게 기본 동작 차단 후 이동
									e.preventDefault();
									moveTo(item);
								}}
								onMouseEnter={() => setActiveIndex(index)}
							>
								<span className='header-suggest__name'>{item.name}</span>
								<span className='header-suggest__code'>{item.code}</span>
								<span className={`stock-badge stock-badge--${item.market.toLowerCase()}`}>{item.market}</span>
							</li>
						))
					)}
				</ul>
			)}
		</div>
	);
}