'use client';

// D3 응원(Cheer) 모달 — 금액/메시지 입력 후 POST /api/posts/{postID}/cheers.
// 규제 가드라인(d3 §⑧): 응원은 사후·자율·무대가. 글 열람 조건 아님.
import { useCallback, useEffect, useState } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { fetchApi } from '@/lib/utils/client';
import type { WalletResponse, CheerSendResponse } from '@/types/reward';
import { sumCash, sumToken } from '@/types/reward';

const PRESET_AMOUNTS = [100, 500, 1000, 5000];
const MAX_MESSAGE = 100;

type Props = {
	postID: number;
	onClose: () => void;
	onDone: () => void;
};

export default function CheerModal({ postID, onClose, onDone }: Props)
{
	const [amount, setAmount] = useState<string>('');
	const [message, setMessage] = useState<string>('');
	const [cash, setCash] = useState<number|null>(null);
	const [token, setToken] = useState<number|null>(null);
	const [busy, setBusy] = useState(false);
	const [error, setError] = useState<string|null>(null);

	// 지갑 가용 잔액 조회 (캐시/토큰 분리 표시 — 응원은 캐시→토큰 순 차감)
	useEffect(() => {
		let cancelled = false;

		(async () => {
			const res = await fetchApi<WalletResponse>('/api/wallet', { silent: true });
			if (cancelled) {
				return;
			}

			if (res.success && res.data) {
				setCash(sumCash(res.data.balances));
				setToken(sumToken(res.data.balances));
			}
			else {
				setCash(null);
				setToken(null);
			}
		})();

		return () => {
			cancelled = true;
		};
	}, []);

	const available = (cash ?? 0) + (token ?? 0);

	const submit = useCallback(async () => {
		setError(null);

		const numeric = Number(amount);

		if (!Number.isInteger(numeric) || numeric <= 0) {
			setError('1 이상의 정수 금액을 입력해 주세요.');
			return;
		}

		if (cash !== null && token !== null && numeric > available) {
			setError('가용 잔액이 부족합니다.');
			return;
		}

		setBusy(true);

		const res = await fetchApi<CheerSendResponse>(`/api/posts/${postID}/cheers`, {
			method: 'POST',
			body: { amount: numeric, message: message.trim() || null },
			silent: true
		});

		setBusy(false);

		if (res.success && res.data) {
			onDone();
		}
		else {
			setError(res.message || '응원에 실패했습니다.');
		}
	}, [amount, message, cash, token, available, postID, onDone]);

	return (
		<Dialog open onOpenChange={(open) => { if (!open) onClose(); }}>
			<DialogContent>
				<DialogHeader>
					<DialogTitle>응원 보내기</DialogTitle>
				</DialogHeader>

				<div className='flex flex-col gap-4'>
					<div className='rounded-md bg-neutral-100 dark:bg-neutral-800 px-3 py-2 text-sm'>
						<div className='flex justify-between'>
							<span className='text-neutral-500'>가용 잔액</span>
							<strong>{cash === null ? '—' : available.toLocaleString()}</strong>
						</div>
						<div className='mt-1 flex justify-between text-xs text-neutral-500'>
							<span>캐시 {cash === null ? '—' : cash.toLocaleString()}</span>
							<span>토큰 {token === null ? '—' : token.toLocaleString()}</span>
						</div>
					</div>

					<div className='flex flex-wrap gap-2'>
						{PRESET_AMOUNTS.map((preset) => (
							<button
								key={preset}
								type='button'
								onClick={() => setAmount(String(preset))}
								className='px-3 py-1.5 rounded-md border border-neutral-300 dark:border-neutral-700 text-sm hover:bg-neutral-100 dark:hover:bg-neutral-800'
							>
								+{preset.toLocaleString()}
							</button>
						))}
					</div>

					<div className='flex flex-col gap-1'>
						<label className='text-sm font-semibold' htmlFor='cheer-amount'>응원 금액</label>
						<input
							id='cheer-amount'
							type='number'
							min={1}
							step={1}
							inputMode='numeric'
							value={amount}
							onChange={(e) => setAmount(e.target.value)}
							placeholder='금액 입력'
							className='border border-neutral-300 dark:border-neutral-700 rounded px-3 py-2 text-sm bg-white dark:bg-neutral-900'
							autoFocus
						/>
					</div>

					<div className='flex flex-col gap-1'>
						<label className='text-sm font-semibold' htmlFor='cheer-message'>
							응원 한마디 <span className='text-xs font-normal text-neutral-400'>(선택)</span>
						</label>
						<textarea
							id='cheer-message'
							value={message}
							onChange={(e) => setMessage(e.target.value.slice(0, MAX_MESSAGE))}
							rows={2}
							maxLength={MAX_MESSAGE}
							placeholder='따뜻한 한마디를 남겨보세요'
							className='border border-neutral-300 dark:border-neutral-700 rounded px-3 py-2 text-sm bg-white dark:bg-neutral-900 resize-none'
						/>
						<div className='text-right text-xs text-neutral-400'>{message.length}/{MAX_MESSAGE}</div>
					</div>

					<p className='text-xs text-neutral-500'>
						* 응원은 자발적이며 글 열람 조건이 아닙니다. 캐시 → 토큰 순으로 차감되며 일부는 플랫폼 수수료로 사용됩니다.
					</p>

					{error && <p className='text-sm text-red-600' role='alert'>{error}</p>}

					<div className='flex justify-end gap-2'>
						<button
							type='button'
							onClick={onClose}
							disabled={busy}
							className='px-4 py-2 rounded-md border border-neutral-300 dark:border-neutral-700 text-sm hover:bg-neutral-100 dark:hover:bg-neutral-800 disabled:opacity-50'
						>
							취소
						</button>
						<button
							type='button'
							onClick={submit}
							disabled={busy}
							className='px-4 py-2 rounded-md bg-red-600 text-white text-sm font-semibold hover:bg-red-700 disabled:opacity-50'
						>
							{busy ? '전송 중...' : '응원하기'}
						</button>
					</div>
				</div>
			</DialogContent>
		</Dialog>
	);
}
