import {
  Injectable,
  CanActivate,
  ExecutionContext,
  BadRequestException,
  UnauthorizedException,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { PrismaService } from '../../prisma/prisma.service';

export const TENANT_KEY = 'tenant';
export const SetTenant = () => Reflector.createDecorator<boolean>();

@Injectable()
export class TenantGuard implements CanActivate {
  constructor(
    private prisma: PrismaService,
    private reflector: Reflector,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    
    // 从请求头获取租户信息
    const tenantCode = request.headers['x-tenant-code'];
    const tenantId = request.headers['x-tenant-id'];
    const host = request.headers['host'];

    let tenantIdValue: number | null = null;

    // 方式1: 从请求头获取租户ID
    if (tenantId) {
      tenantIdValue = parseInt(tenantId, 10);
    }
    // 方式2: 从请求头获取租户编码
    else if (tenantCode) {
      const tenant = await this.prisma.tenant.findUnique({
        where: { code: tenantCode },
      });
      if (!tenant) {
        throw new BadRequestException('租户不存在');
      }
      tenantIdValue = tenant.id;
    }
    // 方式3: 从子域名获取租户（如果配置了domain）
    else if (host) {
      const subdomain = host.split('.')[0];
      if (subdomain && subdomain !== 'www' && subdomain !== 'localhost') {
        const tenant = await this.prisma.tenant.findFirst({
          where: {
            OR: [
              { code: subdomain },
              { domain: subdomain },
            ],
          },
        });
        if (tenant) {
          tenantIdValue = tenant.id;
        }
      }
    }
    // 方式4: 从JWT token中获取（如果用户已登录）
    else if (request.user?.tenantId) {
      tenantIdValue = request.user.tenantId;
    }

    // 如果找到了租户，验证租户是否有效
    if (tenantIdValue) {
      const tenant = await this.prisma.tenant.findUnique({
        where: { id: tenantIdValue },
      });

      if (!tenant) {
        throw new BadRequestException('租户不存在');
      }

      if (tenant.validState !== 1) {
        throw new BadRequestException('租户已失效');
      }

      // 将租户信息附加到请求对象
      request.tenant = tenant;
      request.tenantId = tenantIdValue;
    }

    return true;
  }
}

