import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
  ForbiddenException,
  Logger,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { PrePlantingClient } from './pre-planting.client';

/**
 * 预种授权申请拦截器
 *
 * 仅拦截用户端授权申请路由（POST /authorizations/...）
 * 规则：
 * - 无预种记录（纯认种用户）→ 直接放行
 * - 有预种记录且已合并成树 → 放行
 * - 有预种记录但未合并 → 拦截
 * - planting-service 不可达 → 放行（fail-open，不影响现有功能）
 */
@Injectable()
export class PrePlantingAuthorizationInterceptor implements NestInterceptor {
  private readonly logger = new Logger(PrePlantingAuthorizationInterceptor.name);

  private readonly protectedPaths = [
    '/authorizations/community',
    '/authorizations/province',
    '/authorizations/city',
    '/authorizations/self-apply',
  ];

  constructor(private readonly client: PrePlantingClient) {}

  async intercept(
    context: ExecutionContext,
    next: CallHandler,
  ): Promise<Observable<unknown>> {
    const req = context.switchToHttp().getRequest();

    // 仅拦截 POST 请求
    if (req.method !== 'POST') {
      return next.handle();
    }

    // 仅拦截特定路由
    const reqPath: string = req.path || req.url || '';
    if (!this.protectedPaths.some((p) => reqPath.endsWith(p))) {
      return next.handle();
    }

    const accountSequence = req.user?.accountSequence;
    if (!accountSequence) {
      return next.handle();
    }

    try {
      const eligibility = await this.client.getEligibility(accountSequence);

      // 无预种记录 → 纯认种用户，直接放行
      if (!eligibility.hasPrePlanting) {
        return next.handle();
      }

      // 有预种但未满足条件 → 拦截
      if (!eligibility.canApplyAuthorization) {
        throw new ForbiddenException(
          '须累积购买5份预种计划合并成树后方可申请授权',
        );
      }
    } catch (error) {
      if (error instanceof ForbiddenException) throw error;
      // planting-service 不可达，默认放行
      this.logger.warn(
        `[PRE-PLANTING] Failed to check eligibility for ${accountSequence}, allowing through`,
      );
    }

    return next.handle();
  }
}
