'use client';

import './style.scss';
import { useState, useEffect, useRef, useCallback } from 'react';
import { loadTossPayments } from '@tosspayments/tosspayments-sdk';
import type { TossPaymentsWidgets } from '@tosspayments/tosspayments-sdk';
import { fetchApi } from '@/lib/utils/client';
import useAuth from '@/hooks/useAuth';
import { useConfigContext } from '@/contexts/configProvider';
import { TossCreateOrderRequest } from '@/types/request/payment/charge';
import { TossCreateOrderResponse } from '@/types/response/payment/charge';

const QUICK_AMOUNTS = [10000, 50000, 100000, 1000000];

export default function ChargePage()
{
	// cashInput = 사용자가 충전하려는 캐시 (VAT 제외). VAT 10%는 서버에서 별도 가산.
	const [cashInput, setCashInput] = useState<number>(0);
	const [order, setOrder] = useState<TossCreateOrderResponse|null>(null);
	const [loading, setLoading] = useState(false);
	const [paying, setPaying] = useState(false);
	const [isPopup, setIsPopup] = useState(false);
	const [error, setError] = useState<string|null>(null);
	const { member, loginCheck } = useAuth();
	const config = useConfigContext();
	const isTossTestMode = config?.toss?.tossPayMode === 'test';

	const widgetsRef = useRef<TossPaymentsWidgets|null>(null);

	useEffect(() => {
		setIsPopup(!!window.opener);
	}, []);

	// 주문 생성 후 토스 위젯 초기화 — clientKey/customerKey 로 widgets 생성, 금액 설정, UI 렌더링
	const initWidgets = useCallback(async (created: TossCreateOrderResponse) => {
		const tossPayments = await loadTossPayments(created.clientKey);
		const widgets = tossPayments.widgets({ customerKey: created.customerKey });
		widgetsRef.current = widgets;

		await widgets.setAmount({ value: created.amount, currency: 'KRW' });
		await Promise.all([
			widgets.renderPaymentMethods({ selector: '#toss-payment-methods' }),
			widgets.renderAgreement({ selector: '#toss-agreement' })
		]);
	}, []);

	if (!member || !loginCheck()) {
		return null;
	}

	const handleAmountChange = (value: string) => {
		const num = parseInt(value.replace(/[^0-9]/g, ''), 10);
		setCashInput(isNaN(num) ? 0 : num);
	};

	const addAmount = (add: number) => {
		setCashInput(prev => prev + add);
	};

	// VAT 10% 별도 가산 (표시용). 최종 결제 금액은 서버 주문(order.amount)이 확정한다.
	const vatAmount = Math.round(cashInput * 0.1);
	const totalAmount = cashInput + vatAmount;

	// 1단계: 서버에 주문 생성 → 토스 위젯 초기화
	const handleCreateOrder = async () => {
		if (cashInput < 1000) {
			alert('최소 충전 금액은 1,000원입니다.');
			return;
		}

		setLoading(true);
		setError(null);

		try {
			const res = await fetchApi<TossCreateOrderResponse>('/api/payments/orders', {
				method: 'POST',
				body: { amount: cashInput } as TossCreateOrderRequest
			});

			if (!res.success || !res.data) {
				setError(res.message || '주문 생성에 실패했습니다.');
				setLoading(false);
				return;
			}

			const created = res.data;
			setOrder(created);
			await initWidgets(created);
		} catch (e) {
			console.error('주문 생성/위젯 초기화 실패:', e);
			setError('결제 준비 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.');
		} finally {
			setLoading(false);
		}
	};

	// 2단계: 결제 요청 (redirect 방식) — successUrl/failUrl 로 이동
	const handleRequestPayment = async () => {
		const widgets = widgetsRef.current;
		if (!widgets || !order) {
			return;
		}

		setPaying(true);
		setError(null);

		try {
			const origin = window.location.origin;
			await widgets.requestPayment({
				orderId: order.orderID,
				orderName: order.orderName,
				successUrl: `${origin}/charge/success`,
				failUrl: `${origin}/charge/fail`,
				customerEmail: member.email ?? undefined,
				customerName: member.name ?? undefined
			});
		} catch (e) {
			// 사용자가 결제창을 닫거나 요청이 실패한 경우 — 페이지에 머물러 재시도 가능
			console.error('결제 요청 실패:', e);
			const message = e instanceof Error ? e.message : '결제 요청에 실패했습니다.';
			setError(message);
			setPaying(false);
		}
	};

	// 금액 재선택 — 위젯을 닫고 1단계로 복귀 (금액이 바뀌면 새 주문이 필요)
	const handleReset = () => {
		widgetsRef.current = null;
		setOrder(null);
		setError(null);
	};

	return (
		<div className="charge-page">
			{isTossTestMode && (
				<div className="charge-page__test-banner" role="alert">
					현재 토스 충전은 테스트 환경입니다.
				</div>
			)}
			<div className="charge-page__card">
				<div className="charge-page__header">
					<h1>캐시 충전</h1>
					{isPopup && (
						<button type="button" className="charge-page__close" onClick={() => window.close()}>×</button>
					)}
				</div>

				<div className="charge-page__body">
					{!order && (
						<>
							<label className="charge-page__label">충전 캐시 (원)</label>
							<input
								type="text"
								className="charge-page__amount-input"
								value={cashInput > 0 ? cashInput.toLocaleString() : ''}
								onChange={e => handleAmountChange(e.target.value)}
								placeholder="0"
								inputMode="numeric"
								autoFocus
							/>

							<div className="charge-page__quick-btns">
								{QUICK_AMOUNTS.map(v => (
									<button type="button" key={v} className="charge-page__quick-btn" onClick={() => addAmount(v)}>
										+{v >= 10000 ? `${v / 10000}만` : v.toLocaleString()}
									</button>
								))}
							</div>

							<div className="charge-page__receipt">
								<div className="charge-page__receipt-row">
									<span>충전 캐시</span>
									<span>{cashInput.toLocaleString()} 원</span>
								</div>
								<div className="charge-page__receipt-row">
									<span>부가세 (10%)</span>
									<span>{vatAmount.toLocaleString()} 원</span>
								</div>
								<div className="charge-page__receipt-row charge-page__receipt-row--total">
									<span>총 결제 금액</span>
									<span>{totalAmount.toLocaleString()} 원</span>
								</div>
							</div>

							{error && <p className="charge-page__error" role="alert">{error}</p>}

							<button type="button" className="charge-page__submit" onClick={handleCreateOrder} disabled={loading || cashInput < 1000}>
								{loading ? '결제 준비 중...' : '결제 진행'}
							</button>
						</>
					)}

					{order && (
						<>
							<div className="charge-page__receipt">
								<div className="charge-page__receipt-row">
									<span>충전 캐시</span>
									<span>{order.pointAmount.toLocaleString()} 원</span>
								</div>
								<div className="charge-page__receipt-row">
									<span>부가세 (10%)</span>
									<span>{order.vatAmount.toLocaleString()} 원</span>
								</div>
								<div className="charge-page__receipt-row charge-page__receipt-row--total">
									<span>총 결제 금액</span>
									<span>{order.amount.toLocaleString()} 원</span>
								</div>
							</div>

							<div id="toss-payment-methods" className="charge-page__toss-methods" />
							<div id="toss-agreement" className="charge-page__toss-agreement" />

							{error && <p className="charge-page__error" role="alert">{error}</p>}

							<button type="button" className="charge-page__submit" onClick={handleRequestPayment} disabled={paying}>
								{paying ? '결제 요청 중...' : `${order.amount.toLocaleString()}원 결제하기`}
							</button>
							<button type="button" className="charge-page__reset" onClick={handleReset} disabled={paying}>
								금액 다시 선택
							</button>
						</>
					)}
				</div>
			</div>
		</div>
	);
}
