import { NextRequest, NextResponse } from 'next/server';
import { LoginResponse } from '@/types/response/auth';
import { fetchJson } from '@/lib/utils/server';
import { isSocialLoginProvider, SOCIAL_PROVIDER_LABELS, OAUTH_STATE_COOKIE_PREFIX } from '@/constants/social';

/**
 * 소셜 로그인 콜백 라우트 (Naver/Kakao) — /login/{provider}/callback
 *
 * 1. ?code&state(&error) 수신 → start 라우트가 심은 httpOnly state 쿠키와 대조 (CSRF 방어)
 * 2. 백엔드 POST /api/auth/social-login (code 교환 + userinfo + 계정 매칭)
 * 3. 성공: accessToken/refreshToken httpOnly 쿠키(기존 google/callback 옵션 동일) → /login/{provider}/complete
 * 4. Auth.EmailRequired / Auth.AccountExists: 안내 화면(/login/social-notice)으로 분기
 * 5. 기타 실패: /login?error={message} (로그인 페이지 alert 관례)
 */
export async function GET(request: NextRequest, { params }: { params: Promise<{ provider: string }> })
{
	const { provider } = await params;

	if (!isSocialLoginProvider(provider)) {
		const url = new URL('/login', request.url);
		url.searchParams.set('error', '지원하지 않는 소셜 로그인입니다.');
		return NextResponse.redirect(url);
	}

	const label = SOCIAL_PROVIDER_LABELS[provider];
	const stateCookieName = `${OAUTH_STATE_COOKIE_PREFIX}${provider}`;
	const savedState = request.cookies.get(stateCookieName)?.value ?? null;

	// state 쿠키는 일회용 — 성공/실패와 무관하게 응답에서 제거
	const finish = (response: NextResponse) => {
		response.cookies.delete(stateCookieName);
		return response;
	};

	const failRedirect = (message: string) => {
		const url = new URL('/login', request.url);
		url.searchParams.set('error', message);
		return finish(NextResponse.redirect(url));
	};

	const noticeRedirect = (reason: 'email-required'|'account-exists') => {
		const url = new URL('/login/social-notice', request.url);
		url.searchParams.set('reason', reason);
		url.searchParams.set('provider', provider);
		return finish(NextResponse.redirect(url));
	};

	const searchParams = request.nextUrl.searchParams;
	const code = searchParams.get('code');
	const state = searchParams.get('state');
	const oauthError = searchParams.get('error');
	const oauthErrorDescription = searchParams.get('error_description');

	// 사용자가 동의 화면에서 취소한 경우 등 provider 측 에러
	if (oauthError) {
		if (oauthError === 'access_denied') {
			return failRedirect(`${label} 로그인이 취소되었습니다.`);
		}
		return failRedirect(oauthErrorDescription || `${label} 인증에 실패했습니다. 다시 시도해주세요.`);
	}

	if (!code) {
		return failRedirect(`${label} 인증 코드가 없습니다. 다시 시도해주세요.`);
	}

	if (!state || !savedState || state !== savedState) {
		return failRedirect('로그인 요청 검증(state)에 실패했습니다. 다시 시도해주세요.');
	}

	try {
		const redirectUri = `${request.nextUrl.origin}/login/${provider}/callback`;

		const res = await fetchJson<LoginResponse>('/api/auth/social-login', {
			method: 'POST',
			body: JSON.stringify({
				Provider: provider,
				Code: code,
				State: state,
				RedirectUri: redirectUri
			})
		});

		if (res.success && res.data) {
			const response = NextResponse.redirect(new URL(`/login/${provider}/complete`, request.url));
			const cookieOptions = { httpOnly: true, path: '/' };
			response.cookies.set('accessToken', res.data.accessToken, cookieOptions);
			response.cookies.set('refreshToken', res.data.refreshToken, cookieOptions);
			return finish(response);
		}

		const errorCode = res.errors?.[0]?.code;

		// 카카오 이메일 선택동의 미동의 → 이메일 제공 동의 안내 화면
		if (errorCode === 'Auth.EmailRequired') {
			return noticeRedirect('email-required');
		}

		// 같은 이메일의 기존 계정 존재 (자동연결 금지) → 기존 계정 로그인 + SNS 연동 안내 화면
		if (errorCode === 'Auth.AccountExists') {
			return noticeRedirect('account-exists');
		}

		if (errorCode === 'Auth.SocialNotConfigured') {
			return failRedirect(`${label} 로그인이 아직 준비되지 않았습니다. 잠시 후 다시 시도해주세요.`);
		}

		return failRedirect(res.errors?.[0]?.description || res.message || `${label} 로그인에 실패했습니다. 다시 시도해주세요.`);
	} catch (e) {
		console.error(`[${provider} Callback] Error:`, e);
		return failRedirect(e instanceof Error ? e.message : `${label} 로그인 처리 중 오류가 발생했습니다.`);
	}
}