'use client';

import { useEffect, useRef, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { fetchApi } from '@/lib/utils/client';
import { SnsConnectResponse } from '@/types/sns';
import './style.scss';

const STATE_STORAGE_KEY = 'dpot-sns-google-state';

/**
 * Google OAuth Authorization Code 콜백.
 *
 * 1. URL ?code= ?state= ?error= 수신
 * 2. state 검증 (sessionStorage 저장값과 비교)
 * 3. POST /api/mypage/sns/google/connect (code, redirectUri)
 * 4. 성공 → /sns-link?connected=google
 * 5. 실패 → /sns-link?error={message}
 */
export default function GoogleSnsCallbackPage()
{
	const router = useRouter();
	const searchParams = useSearchParams();
	const [phase, setPhase] = useState<'verifying' | 'success' | 'error'>('verifying');
	const [errorMessage, setErrorMessage] = useState<string|null>(null);
	const handledRef = useRef(false);

	useEffect(() => {
		// React StrictMode 등에서 effect 가 두 번 호출돼 code 가 재사용될 수 있음 → ref 가드
		if (handledRef.current) {
			return;
		}
		handledRef.current = true;

		const code = searchParams.get('code');
		const state = searchParams.get('state');
		const oauthError = searchParams.get('error');

		const finishWithError = (message: string) => {
			setErrorMessage(message);
			setPhase('error');
			window.setTimeout(() => {
				router.replace(`/sns-link?error=${encodeURIComponent(message)}`);
			}, 1200);
		};

		if (oauthError) {
			finishWithError(oauthError);
			return;
		}

		if (!code) {
			finishWithError('Authorization code 가 없습니다.');
			return;
		}

		// state 검증
		let savedState: string|null = null;
		try {
			savedState = window.sessionStorage.getItem(STATE_STORAGE_KEY);
			window.sessionStorage.removeItem(STATE_STORAGE_KEY);
		} catch {
			// silent
		}

		if (!state || !savedState || state !== savedState) {
			finishWithError('state 가 일치하지 않습니다. 다시 시도해주세요.');
			return;
		}

		const redirectUri = `${window.location.origin}/auth/sns/google/callback`;

		(async () => {
			try {
				const res = await fetchApi<SnsConnectResponse>('/api/mypage/sns/google/connect', {
					method: 'POST',
					body: { code, redirectUri },
					silent: true
				});

				if (res.success) {
					setPhase('success');
					window.setTimeout(() => {
						router.replace('/sns-link?connected=google');
					}, 600);
				} else {
					finishWithError(res.message || '연동에 실패했습니다.');
				}
			} catch {
				finishWithError('네트워크 오류로 연동에 실패했습니다.');
			}
		})();
	}, [router, searchParams]);

	return (
		<div className="sns-callback">
			<div className="sns-callback__panel" role="status" aria-live="polite">
				{phase === 'verifying' && (
					<>
						<div className="sns-callback__spinner" aria-hidden="true" />
						<p className="sns-callback__title">Google 계정 연동 처리 중...</p>
						<p className="sns-callback__desc">잠시만 기다려주세요.</p>
					</>
				)}
				{phase === 'success' && (
					<>
						<p className="sns-callback__title">연동이 완료되었습니다!</p>
						<p className="sns-callback__desc">SNS 연결 관리 페이지로 이동합니다.</p>
					</>
				)}
				{phase === 'error' && (
					<>
						<p className="sns-callback__title">연동에 실패했습니다</p>
						<p className="sns-callback__desc">{errorMessage}</p>
					</>
				)}
			</div>
		</div>
	);
}
