import {
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
  SetMetadata,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { DrizzleService } from '@lib/drizzle/src/drizzle.service';
import { eq } from 'drizzle-orm';
import { tnAgency } from 'drizzle/schema';

export const CORP_ANALYSIS_VIEW_KEY = 'corpAnalysisViewLevel';

//* 핸들러/컨트롤러에 필요한 분석관리 노출레벨을 지정 (1: 분석목록 | 2: 상세팝업 포함)
export const CorpAnalysisView = (level: 1 | 2) =>
  SetMetadata(CORP_ANALYSIS_VIEW_KEY, level);

//* 기업관리자/조직관리자(role='corp')의 분석관리 접근을 tn_agency.agc_analysis_view 로 게이팅.
//*   0: 미노출 | 1: 분석목록만 | 2: 분석목록+상세팝업. admin/sales는 무영향.
//*   설정 변경 즉시 반영을 위해 토큰이 아닌 DB를 조회한다.
@Injectable()
export class CorpAnalysisViewGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private drizzle: DrizzleService,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const req = context.switchToHttp().getRequest();
    const admin = req.admin;

    //* 기업 측 관리자가 아니면 통과
    if (!admin || admin.role !== 'corp') return true;

    const required = this.reflector.getAllAndOverride<number>(
      CORP_ANALYSIS_VIEW_KEY,
      [context.getHandler(), context.getClass()],
    );
    if (!required) return true;

    const [agency] = await this.drizzle
      .select({ agcAnalysisView: tnAgency.agcAnalysisView })
      .from(tnAgency)
      .where(eq(tnAgency.agcId, admin.agcId));

    if (!agency || agency.agcAnalysisView < required) {
      throw new ForbiddenException('분석관리 화면 접근 권한이 없습니다');
    }
    return true;
  }
}
