import { OrderDetailService } from '@api/modules/order/order-detail/order-detail.service';
import {
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
} from '@nestjs/common';
import { Request } from 'express';

/**
 * 회원용 분석 조회(oddId 기반)에서 "요청자 == 분석 소유자"를 강제한다.
 *
 * 배경: 이 컨트롤러의 조회들은 소유자 검증이 없어 oddId만 바꾸면 남의 고객
 * 분석(이름/생년/연락처/진료·처방 이력)이 그대로 조회됐다. 자부상(car-basic)만
 * 서비스 단에서 소유자를 대조하고 있었고 나머지는 무방비였다.
 *
 * 토큰이 없거나 memId가 없으면 -1로 떨어져 어떤 주문과도 일치하지 않으므로
 * fail-closed로 차단된다.
 */
@Injectable()
export class OwnAnalysisGuard implements CanActivate {
  constructor(private orderDetailService: OrderDetailService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest<Request>();
    const oddIdRaw = (request.params as Record<string, string>)?.oddId;

    //* oddId 파라미터가 없는 라우트(asbId/acbId 등)는 각 서비스의 기존 검증에 맡긴다.
    if (!oddIdRaw) return true;

    const oddId = Number(oddIdRaw);
    if (!Number.isFinite(oddId)) return true; //* 형식 오류는 ParseIntPipe가 처리

    const viewerMemId = Number(
      (request['user'] as { memId?: number } | undefined)?.memId ?? -1,
    );

    const orderDetail = await this.orderDetailService.getOrderDetail(oddId);
    const ownerMemId = orderDetail?.member?.memId;

    if (ownerMemId === undefined || ownerMemId === null) {
      throw new ForbiddenException('접근 권한이 없습니다');
    }
    if (Number(ownerMemId) !== viewerMemId) {
      throw new ForbiddenException('접근 권한이 없습니다');
    }

    return true;
  }
}
