'use client';

import { useCallback, useEffect, useState } from 'react';
import Link from 'next/link';
import { cn, fetchApi, getDateTime } from '@/lib/utils/client';
import { bpDirection, formatBpPercent, formatTokenNumber } from '@/lib/utils/paper';
import Loading from '@/app/component/Loading';
import Pagination from '@/app/component/Pagination';
import {
	PaperOrderStatus,
	PAPER_SIDE_LABEL,
	PAPER_FILL_RULE_LABEL,
	PAPER_ORDER_STATUS_LABEL,
	PAPER_LEDGER_TYPE_LABEL,
	PaperOrderSide,
	PaperLedgerType
} from '@/types/paper';
import type {
	PaperPositionsResponse,
	PaperPositionRow,
	PaperOrdersResponse,
	PaperOrderRow,
	PaperLedgerResponse,
	PaperLedgerRow,
	PaperOrderStatusValue
} from '@/types/paper';

type TabKey = 'positions'|'orders'|'ledger';
const PER_PAGE = 20;

const STATUS_BADGE_CLASS: Record<PaperOrderStatusValue, string> = {
	[PaperOrderStatus.Pending]: 'paper__badge--pending',
	[PaperOrderStatus.Filled]: 'paper__badge--filled',
	[PaperOrderStatus.Cancelled]: 'paper__badge--cancelled',
	[PaperOrderStatus.Rejected]: 'paper__badge--rejected'
};

export default function PaperPortfolio()
{
	const [tab, setTab] = useState<TabKey>('positions');

	return (
		<div>
			<div className='paper__tabs'>
				<button type='button' className={cn('paper__tab', tab === 'positions' && 'paper__tab--active')} onClick={() => setTab('positions')}>보유</button>
				<button type='button' className={cn('paper__tab', tab === 'orders' && 'paper__tab--active')} onClick={() => setTab('orders')}>주문</button>
				<button type='button' className={cn('paper__tab', tab === 'ledger' && 'paper__tab--active')} onClick={() => setTab('ledger')}>입출금</button>
			</div>

			{tab === 'positions' && <PositionsTab />}
			{tab === 'orders' && <OrdersTab />}
			{tab === 'ledger' && <LedgerTab />}
		</div>
	);
}

// ── 보유 포지션 ──
function PositionsTab()
{
	const [rows, setRows] = useState<PaperPositionRow[]>([]);
	const [loading, setLoading] = useState(true);

	useEffect(() => {
		let cancelled = false;

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

			setRows(res.success ? (res.data?.list ?? []) : []);
			setLoading(false);
		})();

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

	if (loading) {
		return <Loading type={2} />;
	}

	if (rows.length === 0) {
		return <div className='paper__empty'>보유 중인 종목이 없습니다.</div>;
	}

	return (
		<div className='paper__table-wrap'>
			<table className='paper__table'>
				<thead>
					<tr>
						<th className='paper__th--left'>종목</th>
						<th>보유수량</th>
						<th>매도예약</th>
						<th>평균단가</th>
						<th>현재가</th>
						<th>평가금액</th>
						<th>평가손익</th>
						<th>수익률</th>
					</tr>
				</thead>
				<tbody>
					{rows.map(row => {
						const dir = bpDirection(row.unrealizedPnLBp);

						return (
							<tr key={row.stockCode}>
								<td className='paper__td--left'>
									<Link href={`/stock/${row.stockCode}`} className='paper__stock-name'>{row.stockName}</Link>
									<span className='paper__stock-code'>{row.stockCode}</span>
								</td>
								<td>{row.quantity.toLocaleString()}</td>
								<td>{row.reservedQuantity.toLocaleString()}</td>
								<td>{row.avgPrice.toLocaleString('ko-KR', { maximumFractionDigits: 2 })}</td>
								<td>{row.latestClose === null ? '—' : row.latestClose.toLocaleString()}</td>
								<td>{formatTokenNumber(row.marketValue)}</td>
								<td className={cn(`paper__value--${dir}`)}>{formatTokenNumber(row.unrealizedPnL)}</td>
								<td className={cn(`paper__value--${dir}`)}>{formatBpPercent(row.unrealizedPnLBp)}</td>
							</tr>
						);
					})}
				</tbody>
			</table>
		</div>
	);
}

// ── 주문·체결 내역 ──
function OrdersTab()
{
	const [rows, setRows] = useState<PaperOrderRow[]>([]);
	const [total, setTotal] = useState(0);
	const [page, setPage] = useState(1);
	const [status, setStatus] = useState<PaperOrderStatusValue|''>('');
	const [loading, setLoading] = useState(true);
	const [cancelingID, setCancelingID] = useState<number|null>(null);

	const load = useCallback(async () => {
		setLoading(true);

		const query = new URLSearchParams();
		query.set('page', String(page));
		query.set('perPage', String(PER_PAGE));
		if (status !== '') {
			query.set('status', String(status));
		}

		const res = await fetchApi<PaperOrdersResponse>(`/api/paper/orders?${query.toString()}`, { silent: true });

		if (res.success && res.data) {
			setRows(res.data.list);
			setTotal(res.data.total);
		}
		else {
			setRows([]);
			setTotal(0);
		}

		setLoading(false);
	}, [page, status]);

	useEffect(() => {
		load();
	}, [load]);

	const cancelOrder = useCallback(async (id: number) => {
		if (!confirm('주문을 취소하시겠어요?')) {
			return;
		}

		setCancelingID(id);
		const res = await fetchApi(`/api/paper/orders/${id}`, { method: 'DELETE', silent: true });
		setCancelingID(null);

		if (res.success) {
			load();
		}
		else {
			alert(res.message || '주문 취소에 실패했습니다.');
		}
	}, [load]);

	const canCancel = (row: PaperOrderRow) => row.status === PaperOrderStatus.Pending && new Date(row.cancelableUntil).getTime() > Date.now();

	return (
		<div>
			<div className='paper__tab-group'>
				<span className='paper__tab-group-label'>상태</span>
				<button type='button' className={cn('paper__tab', status === '' && 'paper__tab--active')} onClick={() => { setStatus(''); setPage(1); }}>전체</button>
				<button type='button' className={cn('paper__tab', status === PaperOrderStatus.Pending && 'paper__tab--active')} onClick={() => { setStatus(PaperOrderStatus.Pending); setPage(1); }}>접수</button>
				<button type='button' className={cn('paper__tab', status === PaperOrderStatus.Filled && 'paper__tab--active')} onClick={() => { setStatus(PaperOrderStatus.Filled); setPage(1); }}>체결</button>
				<button type='button' className={cn('paper__tab', status === PaperOrderStatus.Cancelled && 'paper__tab--active')} onClick={() => { setStatus(PaperOrderStatus.Cancelled); setPage(1); }}>취소</button>
				<button type='button' className={cn('paper__tab', status === PaperOrderStatus.Rejected && 'paper__tab--active')} onClick={() => { setStatus(PaperOrderStatus.Rejected); setPage(1); }}>거부</button>
			</div>

			{loading ? (
				<Loading type={2} />
			) : rows.length === 0 ? (
				<div className='paper__empty'>주문 내역이 없습니다.</div>
			) : (
				<>
					<div className='paper__table-wrap'>
						<table className='paper__table'>
							<thead>
								<tr>
									<th className='paper__th--left'>종목</th>
									<th className='paper__th--center'>구분</th>
									<th className='paper__th--center'>기준</th>
									<th>수량</th>
									<th>예약금액</th>
									<th>기준일</th>
									<th className='paper__th--center'>상태</th>
									<th>체결가</th>
									<th>실현손익</th>
									<th className='paper__th--center'>취소</th>
								</tr>
							</thead>
							<tbody>
								{rows.map(row => {
									const pnlDir = bpDirection(row.fill?.realizedPnL ?? null);

									return (
										<tr key={row.id}>
											<td className='paper__td--left'>
												<Link href={`/stock/${row.stockCode}`} className='paper__stock-name'>{row.stockName}</Link>
												<span className='paper__stock-code'>{row.stockCode}</span>
											</td>
											<td className='paper__td--center'>
												<span className={cn('paper__badge', row.side === PaperOrderSide.Buy ? 'paper__badge--buy' : 'paper__badge--sell')}>
													{PAPER_SIDE_LABEL[row.side]}
												</span>
											</td>
											<td className='paper__td--center'>{PAPER_FILL_RULE_LABEL[row.fillRule]}</td>
											<td>{row.quantity.toLocaleString()}</td>
											<td>{formatTokenNumber(row.reservedAmount)}</td>
											<td>{row.targetDate}</td>
											<td className='paper__td--center'>
												<span className={cn('paper__badge', STATUS_BADGE_CLASS[row.status])} title={row.rejectReason ?? undefined}>
													{PAPER_ORDER_STATUS_LABEL[row.status]}
												</span>
											</td>
											<td>{row.fill ? row.fill.price.toLocaleString() : '—'}</td>
											<td className={cn(row.fill?.realizedPnL != null && `paper__value--${pnlDir}`)}>
												{row.fill?.realizedPnL != null ? formatTokenNumber(row.fill.realizedPnL) : '—'}
											</td>
											<td className='paper__td--center'>
												{canCancel(row) ? (
													<button
														type='button'
														className='paper__btn paper__btn--danger paper__btn--sm'
														onClick={() => cancelOrder(row.id)}
														disabled={cancelingID === row.id}
													>
														{cancelingID === row.id ? '취소 중' : '취소'}
													</button>
												) : (
													'—'
												)}
											</td>
										</tr>
									);
								})}
							</tbody>
						</table>
					</div>

					<Pagination total={total} page={page} perPage={PER_PAGE} onChange={setPage} />
				</>
			)}
		</div>
	);
}

// ── 입출금 내역 ──
function LedgerTab()
{
	const [rows, setRows] = useState<PaperLedgerRow[]>([]);
	const [total, setTotal] = useState(0);
	const [page, setPage] = useState(1);
	const [loading, setLoading] = useState(true);

	const load = useCallback(async () => {
		setLoading(true);

		const res = await fetchApi<PaperLedgerResponse>(`/api/paper/ledger?page=${page}&perPage=${PER_PAGE}`, { silent: true });

		if (res.success && res.data) {
			setRows(res.data.list);
			setTotal(res.data.total);
		}
		else {
			setRows([]);
			setTotal(0);
		}

		setLoading(false);
	}, [page]);

	useEffect(() => {
		load();
	}, [load]);

	if (loading) {
		return <Loading type={2} />;
	}

	if (rows.length === 0) {
		return <div className='paper__empty'>입출금 내역이 없습니다.</div>;
	}

	return (
		<>
			<div className='paper__table-wrap'>
				<table className='paper__table'>
					<thead>
						<tr>
							<th className='paper__th--center'>구분</th>
							<th>금액</th>
							<th>좌수 변동</th>
							<th>이후 잔액</th>
							<th className='paper__th--left'>일시</th>
						</tr>
					</thead>
					<tbody>
						{rows.map(row => (
							<tr key={row.id}>
								<td className='paper__td--center'>
									<span className={cn('paper__badge', row.type === PaperLedgerType.Deposit ? 'paper__badge--filled' : 'paper__badge--cancelled')}>
										{PAPER_LEDGER_TYPE_LABEL[row.type]}
									</span>
								</td>
								<td>{formatTokenNumber(row.tokenAmount)}</td>
								<td>{row.unitsDelta.toLocaleString('ko-KR', { maximumFractionDigits: 4 })}</td>
								<td>{formatTokenNumber(row.balanceAfter)}</td>
								<td className='paper__td--left'>{getDateTime(row.createdAt)}</td>
							</tr>
						))}
					</tbody>
				</table>
			</div>

			<Pagination total={total} page={page} perPage={PER_PAGE} onChange={setPage} />
		</>
	);
}
