'use client';

import { useCallback, useState, type ChangeEvent, type FormEvent } from 'react';
import { Search } from 'lucide-react';
import { fetchApi } from '@/lib/utils/client';
import type { LiveChannelItem, LiveChannelListResponse } from '@/types/response/channel/live-list';
import LiveChannelCard from '../_components/LiveChannelCard';
import LiveChannelEmpty from '../_components/LiveChannelEmpty';

type SortKey = 'viewers'|'newest'|'name';

type Props = {
	initialChannels: LiveChannelItem[];
	initialTotal: number;
	pageSize: number;
};

const SORT_OPTIONS: { value: SortKey; label: string }[] = [
	{ value: 'viewers', label: '시청자순' },
	{ value: 'newest', label: '최신순' },
	{ value: 'name', label: '채널명순' }
];

export default function LiveExplorer({ initialChannels, initialTotal, pageSize }: Props)
{
	const [channels, setChannels] = useState<LiveChannelItem[]>(initialChannels);
	const [total, setTotal] = useState(initialTotal);
	const [keyword, setKeyword] = useState('');
	const [appliedKeyword, setAppliedKeyword] = useState('');
	const [sort, setSort] = useState<SortKey>('viewers');
	const [loading, setLoading] = useState(false);
	const [error, setError] = useState<string|null>(null);

	const hasMore = channels.length < total;

	const fetchList = useCallback(async (kw: string, sortKey: SortKey, offset: number) => {
		setLoading(true);
		setError(null);

		try {
			const params = new URLSearchParams({ limit: String(pageSize), offset: String(offset), sort: sortKey });
			if (kw) {
				params.set('keyword', kw);
			}

			const res = await fetchApi<LiveChannelListResponse>(`/api/channel/live-list?${params.toString()}`, { silent: true });
			if (res.success && res.data) {
				const data = res.data;
				setChannels(prev => offset === 0 ? data.channels : [...prev, ...data.channels]);
				setTotal(data.total);
			} else {
				setError('목록을 불러오지 못했습니다.');
			}
		} catch {
			setError('목록을 불러오지 못했습니다.');
		} finally {
			setLoading(false);
		}
	}, [pageSize]);

	const handleSearch = useCallback((e: FormEvent) => {
		e.preventDefault();
		setAppliedKeyword(keyword);
		fetchList(keyword, sort, 0);
	}, [keyword, sort, fetchList]);

	const handleSortChange = useCallback((e: ChangeEvent<HTMLSelectElement>) => {
		const next = e.target.value as SortKey;
		setSort(next);
		fetchList(appliedKeyword, next, 0);
	}, [appliedKeyword, fetchList]);

	const handleLoadMore = useCallback(() => {
		if (loading || !hasMore) {
			return;
		}

		fetchList(appliedKeyword, sort, channels.length);
	}, [loading, hasMore, appliedKeyword, sort, channels.length, fetchList]);

	return (
		<section className="live-page" aria-labelledby="live-page-heading">
			<header className="live-page__head">
				<h1 id="live-page-heading" className="live-page__title">
					생방송
					<span className="live-page__count">{total.toLocaleString()}</span>
				</h1>

				<form className="live-page__controls" onSubmit={handleSearch}>
					<select className="live-page__sort" value={sort} onChange={handleSortChange} aria-label="정렬">
						{SORT_OPTIONS.map(o => (
							<option key={o.value} value={o.value}>{o.label}</option>
						))}
					</select>
					<input
						type="search"
						className="live-page__search"
						value={keyword}
						onChange={e => setKeyword(e.target.value)}
						placeholder="채널명 또는 핸들 검색"
						aria-label="검색"
					/>
					<button type="submit" className="live-page__search-btn" aria-label="검색"><Search size={18} /></button>
				</form>
			</header>

			{channels.length === 0 ? (
				<LiveChannelEmpty />
			) : (
				<div className="live-grid" role="list">
					{channels.map((ch, idx) => (
						<div key={ch.channelSID} role="listitem" className="live-grid__item">
							<LiveChannelCard channel={ch} priority={idx < 4} />
						</div>
					))}
				</div>
			)}

			{hasMore && (
				<div className="home__load-more">
					<button type="button" onClick={handleLoadMore} disabled={loading} className="home__load-more-btn">
						{loading ? '불러오는 중...' : '더 보기'}
					</button>
				</div>
			)}

			{error && <div role="alert" className="home__error">{error}</div>}
		</section>
	);
}