'use client';

import './style.scss';
import { useState, useEffect } from 'react';
import { LoginLogType, WalletLogCategory } from '@/constants/common';
import { fetchApi, getDateTime } from '@/lib/utils/client';
import type { ChargeLogsResponse } from '@/types/response/account/chargeLogs';
import Loading from '@/app/component/Loading';
import Pagination from '@/app/component/Pagination';
import NavTabs from '../navTabs';

const STATUS_MAP: Record<string, { label: string; cls: string }> = {
	Paid: { label: '완료', cls: 'status--paid' },
	Pending: { label: '대기', cls: 'status--pending' },
	WaitingDeposit: { label: '입금대기', cls: 'status--pending' },
	Failed: { label: '실패', cls: 'status--failed' },
	Cancelled: { label: '취소', cls: 'status--cancelled' }
};

const METHOD_MAP: Record<string, string> = {
	Card: '신용카드',
	VirtualAccount: '가상계좌',
	Mobile: '휴대폰',
	Transfer: '계좌이체',
	NaverPay: '네이버페이',
	KakaoPay: '카카오페이',
	Payco: '페이코',
	Integrated: '통합결제'
};

const TX_TYPE_MAP: Record<string, string> = {
	Charge: '충전',
	RewardEarned: '보상 적립',
	Spend: '사용',
	Refund: '환불',
	Lock: '잠금',
	Unlock: '잠금 해제',
	Adjusted: '운영자 조정',
	OrderPay: '상점 결제',
	OrderRefund: '주문 환불',
	OrderChannelReward: '상점 채널 보상',
	OrderRefundChannelReward: '상점 보상 차감'
};

const BALANCE_TYPE_MAP: Record<string, string> = {
	PgCharged: 'PG 충전',
	Deposit: '예치금',
	Reward: '보상',
	Airdrop: '에어드랍',
	Locked: '잠금',
	Adjusted: '운영자 조정',
	StoreRevenue: '상점 수익'
};

// 적립류 (+), 사용류 (-) 분류 — UI 표시용 부호
const EARN_TX_TYPES = new Set(['Charge', 'RewardEarned', 'Unlock', 'OrderChannelReward', 'OrderRefund', 'Refund']);

export default function ChargeLogs()
{
	const [error, setError] = useState<string>('');
	const [loading, setLoading] = useState<boolean>(true);
	const [page, setPage] = useState<number>(1);
	const [type, setType] = useState<LoginLogType>(LoginLogType.Today);
	const [category, setCategory] = useState<WalletLogCategory>(WalletLogCategory.Charge);
	const [data, setData] = useState<ChargeLogsResponse>({
		total: 0,
		list: []
	});

	useEffect(() => {
		if (error) {
			alert(error);
			setError('');
		}
	}, [error]);

	useEffect(() => {
		setLoading(true);

		fetchApi<ChargeLogsResponse>(`/api/mypage/charge-logs?type=${type}&category=${category}&page=${page}&perPage=20`).then((res) => {
			setData(res.data!);
		}).catch(err => {
			setError(err.message);
		}).finally(() => {
			setLoading(false);
		});

	}, [type, category, page]);

	useEffect(() => {
		setPage(1);
	}, [type, category]);

	const tabItems = [
		{ label: "오늘", value: LoginLogType.Today },
		{ label: "1주일", value: LoginLogType.Week },
		{ label: "1개월", value: LoginLogType.Month },
		{ label: "3개월", value: LoginLogType.QuarterYear },
		{ label: "6개월", value: LoginLogType.HalfYear }
	];

	const categoryItems = [
		{ label: '전체', value: WalletLogCategory.All },
		{ label: '충전', value: WalletLogCategory.Charge },
		{ label: '적립', value: WalletLogCategory.Earn },
		{ label: '사용', value: WalletLogCategory.Spend },
		{ label: '환불', value: WalletLogCategory.Refund }
	];

	const getStatus = (status: string|null) => status ? (STATUS_MAP[status] ?? { label: status, cls: '' }) : { label: '', cls: '' };
	const getMethod = (method: string|null) => method ? (METHOD_MAP[method] ?? method) : '';
	const getTxType = (txType: string|null) => txType ? (TX_TYPE_MAP[txType] ?? txType) : '';
	const getBalanceType = (bt: string|null) => bt ? (BALANCE_TYPE_MAP[bt] ?? bt) : '';
	const isEarn = (txType: string|null) => txType !== null && EARN_TX_TYPES.has(txType);

	const isCharge = category === WalletLogCategory.Charge;

	return (
		<>
		<NavTabs />

		<div id="chargeLogs">
			{loading && <Loading />}

			<h1>(P) 충전 내역</h1>
			<div className="charge-logs__header">
				<div className="charge-logs__summary">합계: {data.total}</div>
				<div className="charge-logs__tabs">
					<select
						className="charge-logs__filter"
						value={category}
						onChange={(e) => setCategory(e.target.value as WalletLogCategory)}
					>
						{categoryItems.map((item) => (
							<option key={item.value} value={item.value}>{item.label}</option>
						))}
					</select>
					{tabItems.map((item, i) => (
						<button type="button" key={i} className={type === item.value ? 'active' : ''}
							onClick={() => setType(item.value)}>{item.label}
						</button>
					))}
				</div>
			</div>

			<section className={`charge-logs__list ${isCharge ? 'charge-logs__list--charge' : 'charge-logs__list--wallet'}`}>
				<article>
					{isCharge ? (
						<ul>
							<li>일시</li>
							<li>주문번호</li>
							<li>결제 수단</li>
							<li>결제 금액</li>
							<li>캐시</li>
							<li>상태</li>
						</ul>
					) : (
						<ul>
							<li>일시</li>
							<li>구분</li>
							<li>사유</li>
							<li>잔액 유형</li>
							<li>금액</li>
							<li>잔액 후</li>
						</ul>
					)}
				</article>
				<article>
					{data.list.length > 0 ? (
						data.list.map((row) => {
							if (isCharge || row.category === 'charge') {
								const st = getStatus(row.status);
								return (
									<section key={row.id}>
										{/* PC */}
										<ol>
											<li>{getDateTime(row.paidAt ?? row.createdAt)}</li>
											<li className="charge-logs__order-id">{row.orderID}</li>
											<li>{getMethod(row.paymentMethod)}</li>
											<li>{row.amount.toLocaleString()}원</li>
											<li className="amount-plus">+{(row.pointAmount ?? 0).toLocaleString()}P</li>
											<li><span className={st.cls}>{st.label}</span></li>
										</ol>

										{/* Mobile */}
										<dl hidden>
											<dt>
												<div className='flex justify-between'>
													<div>{row.amount.toLocaleString()}원 충전</div>
													<div>
														<small className="charge-logs__order-id">{row.orderID}</small>
													</div>
												</div>
											</dt>
											<dd>
												<ul>
													<li className="amount-plus">+{(row.pointAmount ?? 0).toLocaleString()}P</li>
													<li><span className={st.cls}>{st.label}</span></li>
													<li>{getDateTime(row.paidAt ?? row.createdAt)}</li>
												</ul>
											</dd>
										</dl>
									</section>
								);
							}

							// all/earn/spend/refund 행
							const earn = isEarn(row.txType);
							const sign = earn ? '+' : '-';
							const amountCls = earn ? 'amount-plus' : 'amount-minus';

							return (
								<section key={row.id}>
									{/* PC */}
									<ol>
										<li>{getDateTime(row.createdAt)}</li>
										<li>{getTxType(row.txType)}</li>
										<li className="charge-logs__reason" title={row.reason ?? ''}>{row.reason}</li>
										<li>{getBalanceType(row.balanceType)}</li>
										<li className={amountCls}>{sign}{row.amount.toLocaleString()}P</li>
										<li>{(row.balanceAfter ?? 0).toLocaleString()}P</li>
									</ol>

									{/* Mobile */}
									<dl hidden>
										<dt>
											<div className='flex justify-between'>
												<div>{getTxType(row.txType)}</div>
												<div className={amountCls}>{sign}{row.amount.toLocaleString()}P</div>
											</div>
										</dt>
										<dd>
											<ul>
												<li>{getBalanceType(row.balanceType)}</li>
												<li className="charge-logs__reason">{row.reason}</li>
												<li>{getDateTime(row.createdAt)}</li>
											</ul>
										</dd>
									</dl>
								</section>
							);
						})
					) : (
						<p className="empty">기록이 없습니다.</p>
					)}
				</article>
			</section>

			{data.list.length > 0 && (
				<Pagination total={data.total} page={page} perPage={20} onChange={setPage} />
			)}
		</div>
		</>
	);
}
