import {
    Injectable,
    CanActivate,
    ExecutionContext,
    Logger,
} from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { ROLES_KEY } from '../decorators/roles.decorator'

@Injectable()
export class RolesGuard implements CanActivate {
    private readonly logger = new Logger(RolesGuard.name)

    constructor(private reflector: Reflector) { }

    canActivate(context: ExecutionContext): boolean {
        const request = context.switchToHttp().getRequest()

        const method = request.method
        const url = request.originalUrl
        const user = request.user

        const roleName = user?.role?.code
        const userId = user?.id
        const userEmail = user?.email

        const requiredRoles = this.reflector.getAllAndOverride<string[]>(
            ROLES_KEY,
            [context.getHandler(), context.getClass()],
        )

        const logContext = {
            method,
            url,
            userId,
            userEmail,
            role: roleName,
            requiredRoles,
        }

        // // 🔹 Start check
        // this.logger.debug(
        //     `[ACCESS_CHECK] RolesGuard`,
        //     JSON.stringify(logContext),
        // )

        // 🔹 No user (unauthenticated)
        if (!user) {
            this.logger.warn(
                `[UNAUTHORIZED] No user in request`,
                JSON.stringify(logContext),
            )
            return false
        }

        // 🔹 No roles required → allow
        if (!requiredRoles || requiredRoles.length === 0) {
            this.logger.debug(
                `[AUTHORIZED] No roles required`,
                // JSON.stringify(logContext),
            )
            return true
        }

        // 🔹 Role missing
        if (!roleName) {
            this.logger.warn(
                `[FORBIDDEN] User has no role`,
                JSON.stringify(logContext),
            )
            return false
        }

        // 🔹 Role mismatch
        const isAllowed = requiredRoles.includes(roleName)

        if (!isAllowed) {
            this.logger.warn(
                `[FORBIDDEN] Role mismatch`,
                JSON.stringify(logContext),
            )
            return false
        }

        // 🔹 Success
        this.logger.debug(
            `[AUTHORIZED] Access granted`,
            // JSON.stringify(logContext),
        )

        return true
    }
}