import { CanActivate, ExecutionContext, ForbiddenException, Injectable, UnauthorizedException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AccountStatus, EstateStatus, UserRole } from '@prisma/client';
import { PrismaService } from '../database/prisma.service';
import { IS_PUBLIC_ROUTE } from './public.decorator';

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

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_ROUTE, [
      context.getHandler(),
      context.getClass()
    ]);
    if (isPublic) {
      return true;
    }

    const request = context.switchToHttp().getRequest<{
      user?: { id: string; estateId: string | null; role: UserRole };
    }>();
    const user = request.user;
    if (!user || user.role === UserRole.SUPER_ADMIN || user.role === UserRole.SALES_ADMIN) {
      return true;
    }

    const account = await this.prisma.user.findUnique({
      where: { id: user.id },
      select: {
        status: true,
        estate: {
          select: {
            status: true,
            signupStatus: true
          }
        }
      }
    });

    if (!account || account.status !== AccountStatus.ACTIVE) {
      throw new UnauthorizedException('Account is not active');
    }

    if (!account.estate || account.estate.status !== EstateStatus.ACTIVE) {
      throw new ForbiddenException('Estate is not active');
    }

    return true;
  }
}
