'use client';

import { useEffect, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { CreditCard, Gamepad2, Package, Ticket, Trash2 } from 'lucide-react';
import { fetchApi } from '@/lib/utils/client';
import PayButton, { type PayButtonState } from '@/app/component/PayButton';
import useAuth from '@/hooks/useAuth';
import useCart from '@/hooks/useCart';
import type {
	ProductType,
	ChannelSearchResponse,
	ChannelSearchRow
} from '@/types/store';

const TYPE_BADGE_CLASS: Record<ProductType, string> = {
	1: 'bg-sky-100 text-sky-800 dark:bg-sky-900/40 dark:text-sky-300',
	2: 'bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-300'
};

const TYPE_LABEL: Record<ProductType, string> = { 1: '실물', 2: '쿠폰' };

function TypeBadge({ type }: { type: ProductType })
{
	const Icon = type === 2 ? Ticket : Package;

	return (
		<span
			title={TYPE_LABEL[type]}
			aria-label={TYPE_LABEL[type]}
			className={`inline-flex items-center justify-center p-1 rounded ${TYPE_BADGE_CLASS[type]}`}
		>
			<Icon className="size-3" />
		</span>
	);
}

function formatPrice(n: number): string
{
	return n.toLocaleString('ko-KR');
}

export default function CartPage()
{
	const router = useRouter();
	const { loginCheck } = useAuth();
	const { items, channel, updateQuantity, removeItem, setChannel, clear, totalCount, totalPrice } = useCart();

	const [payState] = useState<PayButtonState>('idle');
	const [submitError, setSubmitError] = useState<string|null>(null);
	const [channelModalOpen, setChannelModalOpen] = useState(false);
	const [optedOut, setOptedOut] = useState(false);
	const [pendingCheckout, setPendingCheckout] = useState(false);

	const requireChannel = items.some(i => i.requireDonationChannel);

	const handleCheckout = () => {
		if (!loginCheck()) {
			return;
		}

		if (items.length === 0) {
			setSubmitError('장바구니가 비어있습니다.');
			return;
		}

		setSubmitError(null);

		// 후원 채널 확인 절차 강제 — 채널 미선택 시 (필수이거나 아직 선택안함 미체크면) 모달 먼저 오픈
		if (!channel && (requireChannel || !optedOut)) {
			setPendingCheckout(true);
			setChannelModalOpen(true);
			return;
		}

		// 실제 결제는 /checkout 영수증 페이지에서 진행
		router.push('/checkout');
	};

	return (
		<div className='container mx-auto max-w-5xl px-4 py-6'>
			<h1 className='text-2xl font-bold mb-4'>
				장바구니{' '}
				<span className='text-red-600 dark:text-red-400 text-xl font-extrabold'>
					({totalCount.toLocaleString()}개)
				</span>
			</h1>

			{items.length === 0 ? (
				<div className='text-center py-20'>
					<p className='text-neutral-500 mb-4'>장바구니가 비어있습니다.</p>
					<Link href='/store' className='inline-block bg-blue-600 text-white px-5 py-2 rounded hover:bg-blue-700 text-sm'>
						상점 둘러보기
					</Link>
				</div>
			) : (
				<div className='grid grid-cols-1 lg:grid-cols-[1fr_360px] gap-6'>
					{/* 좌측: 상품 라인 리스트 */}
					<div className='space-y-3'>
						{items.map((item) => (
							<div
								key={item.productID}
								className='flex gap-3 p-3 border border-neutral-200 dark:border-neutral-800 rounded-lg bg-white dark:bg-neutral-900'
							>
								<Link href={`/store/${item.productID}`} className='shrink-0'>
									<div className='w-20 h-20 sm:w-24 sm:h-24 bg-neutral-100 dark:bg-neutral-800 rounded overflow-hidden flex items-center justify-center'>
										{item.thumbnail ? (
											// eslint-disable-next-line @next/next/no-img-element
											<img src={item.thumbnail} alt={item.name} className='w-full h-full object-cover' />
										) : (
											<span className='text-neutral-400 text-[10px]'>이미지 없음</span>
										)}
									</div>
								</Link>

								<div className='flex-1 min-w-0 flex flex-col justify-between'>
									<div>
										<div className='flex items-center gap-1.5 mb-1'>
											<TypeBadge type={item.type} />
											<Gamepad2 className='size-3.5 shrink-0 text-purple-600 dark:text-purple-400' />
											<span className='text-xs font-semibold text-purple-600 dark:text-purple-400 truncate'>
												{item.gameName}
											</span>
										</div>
										<Link
											href={`/store/${item.productID}`}
											className='text-sm font-semibold line-clamp-2 hover:underline'
										>
											{item.name}
										</Link>
									</div>

									<div className='flex items-end justify-between gap-2 mt-2 flex-wrap'>
										<div className='flex items-stretch border border-neutral-300 dark:border-neutral-700 rounded overflow-hidden text-sm'>
											<button
												type='button'
												onClick={() => { updateQuantity(item.productID, item.quantity - 1); }}
												className='px-2 hover:bg-neutral-100 dark:hover:bg-neutral-800'
												aria-label='수량 감소'
											>
												-
											</button>
											<input
												type='number'
												min={1}
												max={999}
												value={item.quantity}
												onChange={(e) => {
													const v = parseInt(e.target.value || '1', 10);
													updateQuantity(item.productID, isNaN(v) ? 1 : v);
												}}
												className='w-12 text-center bg-white dark:bg-neutral-900 outline-none border-0 appearance-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none'
											/>
											<button
												type='button'
												onClick={() => { updateQuantity(item.productID, item.quantity + 1); }}
												className='px-2 hover:bg-neutral-100 dark:hover:bg-neutral-800'
												aria-label='수량 증가'
											>
												+
											</button>
										</div>

										<div className='text-right'>
											<div className='text-xs text-neutral-500'>{formatPrice(item.price)}P × {item.quantity}</div>
											<div className='text-base font-bold text-red-600 dark:text-red-400'>
												{formatPrice(item.price * item.quantity)}P
											</div>
										</div>

										<button
											type='button'
											onClick={() => { removeItem(item.productID); }}
											className='text-xs text-neutral-500 hover:text-red-600 underline'
										>
											삭제
										</button>
									</div>
								</div>
							</div>
						))}

						<div className='flex justify-between items-center pt-2'>
							<button
								type='button'
								onClick={() => {
									if (confirm('장바구니를 비우시겠습니까?')) {
										clear();
									}
								}}
								className='inline-flex items-center gap-1 text-xs text-neutral-500 hover:text-neutral-700 dark:hover:text-neutral-300'
							>
								<Trash2 className='size-3.5' aria-hidden />
								<span className='underline'>장바구니 비우기</span>
							</button>
							<Link href='/store' className='text-xs text-blue-600 dark:text-blue-400 hover:underline'>
								쇼핑 계속하기 〉
							</Link>
						</div>
					</div>

					{/* 우측: 결제 패널 */}
					<div className='lg:sticky lg:top-4 lg:self-start'>
						<div className='border border-neutral-200 dark:border-neutral-800 rounded-lg bg-white dark:bg-neutral-900 p-4'>
							<h2 className='text-sm font-bold mb-3'>주문 요약</h2>

							<div className='space-y-2 mb-4'>
								<div className='flex justify-between text-sm'>
									<span className='text-neutral-500'>상품 수</span>
									<span>{totalCount}개</span>
								</div>
								<div className='flex justify-between text-sm'>
									<span className='text-neutral-500'>상품 금액</span>
									<span>{formatPrice(totalPrice)}P</span>
								</div>
							</div>

							<div className='border-t border-neutral-200 dark:border-neutral-800 pt-3 mb-3'>
								<label className='block text-xs font-semibold mb-1.5'>후원 채널 {requireChannel ? <span className='text-amber-600 dark:text-amber-400'>(필수)</span> : '(선택)'}</label>
								<button
									type='button'
									onClick={() => { if (loginCheck()) { setChannelModalOpen(true); } }}
									className='w-full border border-neutral-300 dark:border-neutral-700 rounded px-3 py-2 text-sm text-left bg-white dark:bg-neutral-900 hover:bg-neutral-50 dark:hover:bg-neutral-800 truncate'
								>
									{channel ? (
										<span className='font-semibold'>{channel.name}</span>
									) : (
										<span className='text-neutral-400'>후원 채널 선택</span>
									)}
								</button>
								{channel && (
									<button
										type='button'
										onClick={() => { setChannel(null); }}
										className='text-[11px] text-neutral-500 underline mt-1'
									>
										채널 해제
									</button>
								)}
							</div>

							<div className='border-t border-neutral-200 dark:border-neutral-800 pt-3 mb-4'>
								<div className='flex justify-between font-bold text-lg'>
									<span>결제 금액</span>
									<span className='text-red-600 dark:text-red-400'>{formatPrice(totalPrice)}P</span>
								</div>
							</div>

							{submitError && (
								<div className='text-red-600 text-sm mb-2'>{submitError}</div>
							)}

							<PayButton
								state={payState}
								label='전체 구매하기'
								icon={<CreditCard className='size-5' aria-hidden />}
								onClick={handleCheckout}
								disabled={items.length === 0}
							/>

							<p className='text-xs text-neutral-500 mt-2'>
								* 결제 시 캐시·코인 잔액에서 차감됩니다.
							</p>
						</div>
					</div>
				</div>
			)}

			{channelModalOpen && (
				<ChannelSelectModal
					requireChannel={requireChannel}
					onClose={() => { setChannelModalOpen(false); setPendingCheckout(false); }}
					onSelect={(ch) => {
						setChannel(ch);
						setOptedOut(false);
						setChannelModalOpen(false);
						if (pendingCheckout) {
							setPendingCheckout(false);
							router.push('/checkout');
						}
					}}
					onSkip={() => {
						setChannel(null);
						setOptedOut(true);
						setChannelModalOpen(false);
						if (pendingCheckout) {
							setPendingCheckout(false);
							router.push('/checkout');
						}
					}}
				/>
			)}
		</div>
	);
}

function ChannelSelectModal({ onClose, onSelect, onSkip, requireChannel }: {
	onClose: () => void;
	onSelect: (ch: ChannelSearchRow) => void;
	onSkip: () => void;
	requireChannel: boolean;
})
{
	const [keyword, setKeyword] = useState('');
	const [channels, setChannels] = useState<ChannelSearchRow[]>([]);
	const [loading, setLoading] = useState(false);

	useEffect(() => {
		const handle = setTimeout(async () => {
			setLoading(true);
			const params = new URLSearchParams();

			if (keyword.trim()) {
				params.set('keyword', keyword.trim());
			}
			else {
				params.set('random', 'true');
			}

			params.set('page', '1');
			params.set('perPage', '5');

			const res = await fetchApi<ChannelSearchResponse>(`/api/store/channels/search?${params.toString()}`, { silent: true });

			if (res.success && res.data) {
				setChannels(res.data.list);
			}

			setLoading(false);
		}, 300);

		return () => { clearTimeout(handle); };
	}, [keyword]);

	return (
		<div
			className='fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4'
			onClick={onClose}
		>
			<div
				className='bg-white dark:bg-neutral-900 rounded-lg w-full max-w-md max-h-[80vh] flex flex-col'
				onClick={(e) => { e.stopPropagation(); }}
			>
				<div className='p-4 border-b border-neutral-200 dark:border-neutral-800'>
					<div className='flex justify-between items-center mb-3'>
						<h2 className='font-bold'>후원 채널 선택</h2>
						<button type='button' onClick={onClose} className='text-neutral-500 hover:text-neutral-700'>✕</button>
					</div>
					<input
						type='search'
						value={keyword}
						onChange={(e) => { setKeyword(e.target.value); }}
						placeholder='채널명, 핸들, 후원 코드 검색'
						className='w-full border border-neutral-300 dark:border-neutral-700 rounded px-3 py-2 text-sm bg-white dark:bg-neutral-900'
						maxLength={100}
					/>
					{!keyword.trim() ? (
						<p className='text-[11px] text-neutral-400 mt-1'>* 채널이 무작위 순서로 표시됩니다.</p>
					) : (
						<p className='text-[11px] text-neutral-400 mt-1'>* 후원 코드는 정확히 입력해야 합니다.</p>
					)}
				</div>
				<div className='flex-1 overflow-y-auto p-2'>
					{loading ? (
						<div className='text-center py-8 text-neutral-500 text-sm'>검색 중...</div>
					) : channels.length === 0 ? (
						<div className='text-center py-8 text-neutral-500 text-sm'>채널이 없습니다.</div>
					) : (
						channels.map((ch) => (
							<button
								key={ch.id}
								type='button'
								onClick={() => { onSelect(ch); }}
								className='w-full text-left flex items-center gap-3 p-3 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded'
							>
								{ch.thumbnailUrl ? (
									// eslint-disable-next-line @next/next/no-img-element
									<img src={ch.thumbnailUrl} alt='' className='w-10 h-10 rounded-full object-cover' />
								) : (
									<div className='w-10 h-10 rounded-full bg-neutral-300 dark:bg-neutral-700' />
								)}
								<div className='flex-1 min-w-0'>
									<div className='font-semibold truncate flex items-center gap-1'>
										{ch.name}
										{ch.isVerified && (
											<span className='text-[10px] bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 rounded px-1'>✓</span>
										)}
										{ch.donationCode && (
											<span className='text-[10px] font-mono bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300 rounded px-1 tracking-wider'>{ch.donationCode}</span>
										)}
									</div>
									{ch.handle && (
										<div className='text-xs text-neutral-500 truncate'>{ch.handle}</div>
									)}
								</div>
							</button>
						))
					)}
				</div>
				{requireChannel ? (
					<div className='p-3 border-t border-neutral-200 dark:border-neutral-800 text-xs text-amber-600 dark:text-amber-400'>
						후원 채널 선택이 필수인 상품입니다.
					</div>
				) : (
					<div className='p-3 border-t border-neutral-200 dark:border-neutral-800'>
						<label className='flex items-center gap-2 text-sm cursor-pointer text-neutral-600 dark:text-neutral-300'>
							<input type='checkbox' onChange={(e) => { if (e.target.checked) { onSkip(); } }} className='size-4' />
							<span>선택 안함</span>
						</label>
					</div>
				)}
			</div>
		</div>
	);
}
