import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ConfigService } from '@nestjs/config';
import { Strategy, type KakaoProfile } from 'passport-kakao';
import { AuthService } from '../auth.service';
import { CookieStateStore } from './cookie-state.store';
import type { PublicUser } from '../../user/user.service';

// 카카오 OAuth 전략 — 콜백 프로필을 정규화해 AuthService 로 위임.
// 키 미설정 환경에서는 모듈이 이 전략을 등록하지 않는다(AuthModule 팩토리 가드).
@Injectable()
export class KakaoStrategy extends PassportStrategy(Strategy, 'kakao') {
  constructor(
    config: ConfigService,
    private readonly authService: AuthService,
  ) {
    super({
      clientID: config.getOrThrow<string>('KAKAO_CLIENT_ID'),
      clientSecret: config.get<string>('KAKAO_CLIENT_SECRET') ?? '',
      callbackURL: config.getOrThrow<string>('KAKAO_CALLBACK_URL'),
      // store: 쿠키 기반 state 저장소(OAuth CSRF 방지)
      store: new CookieStateStore(),
    });
  }

  // 카카오 프로필(_json)에서 이메일/닉네임/프로필이미지 정규화 후 위임
  async validate(
    _accessToken: string,
    _refreshToken: string,
    profile: KakaoProfile,
  ): Promise<PublicUser> {
    const account = profile._json?.kakao_account;
    const email = account?.email ?? null;
    // 카카오가 이메일 보유+검증을 확인했는지(is_email_verified)
    const emailVerified = account?.is_email_verified === true;
    const name =
      account?.profile?.nickname ||
      profile._json?.properties?.nickname ||
      profile.displayName ||
      email?.split('@')[0] ||
      '카카오 사용자';
    const avatarUrl =
      account?.profile?.profile_image_url ??
      profile._json?.properties?.profile_image ??
      null;
    return this.authService.validateOrCreateOAuthUser({
      provider: 'kakao',
      email,
      emailVerified,
      name,
      avatarUrl,
    });
  }
}
