import { BadRequestException, HttpException, HttpStatus, Injectable, UnauthorizedException } from '@nestjs/common';
import { Types } from 'mongoose';
// import { config } from 'dotenv';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { JwtService } from '@nestjs/jwt';
// import * as dto from '../dto/index'
// import { SessionService } from 'src/session/session.service';
import { log } from 'console';
// import { ModelService } from 'src/model/model.service';
import { ModelService } from '../model/model.service';
import { ConfigService } from '@nestjs/config';
import { types } from 'util';
import { UserStatus } from '../model/schema/user.schema';

@Injectable()
export class AuthService {
    private admin_scope
    private vendor_scope


    constructor(
        private jwtservice: JwtService,
        private model: ModelService,
        private ConfigService: ConfigService
    ) {
        this.admin_scope = this.ConfigService.get<string>('ADMIN_SCOPE')
        this.vendor_scope = this.ConfigService.get<string>('VENDOR_SCOPE');

    }

    async verifyToken(payload: any) {

        let { scope } = payload;
        let query: any;

        if (scope == this.admin_scope) {
            let { _id: admin_id, token_gen_at } = payload;
            query = {
                admin_id: new Types.ObjectId(admin_id),
                access_token: { $ne: null },
                token_gen_at: token_gen_at
            }
        }
        if (scope == this.vendor_scope) {
            let { _id: vendor_id, token_gen_at } = payload;
            query = {
                vendor_id: new Types.ObjectId(vendor_id),
                // access_token: { $ne: null },
                token_gen_at: token_gen_at
            }
        }
        let projection = { __v: 0 }
        let option = { lean: true }
        // console.log("query.with scope....", query);

        let fetch_data: any = await this.model.SessionModel.find(query, projection, option)
        // console.log("fetch_data.....", fetch_data);
        // console.log("fetch data length---->", fetch_data.length)
        if (fetch_data.length) {
            return fetch_data
        }
        else {
            throw new UnauthorizedException("Unauthorized")
        }
    }


    async admin_check(payload: any, api_path: any) {
        try {

            let { _id, scope } = payload;
            let query = { _id: _id }

            let fetch_admin: any = await this.model.UserModel.find(query, {}, { lean: true })

            if (fetch_admin?.length > 0) {
                let { roles, super_admin } = fetch_admin[0];
                let split_api_path = api_path?.split('/');
                let new_path = split_api_path[2];
                let second_new_path = new_path.split('?')[0]
                let type = second_new_path.toUpperCase();
                // console.log("type.......", type);
                // console.log("roles.......", roles);

                if (super_admin != true && type != "PROFILE") {
                    let check_roles = roles.includes(type);
                    if (check_roles != true) {
                        throw new UnauthorizedException();
                    }
                }
            }
            fetch_admin[0].scope = scope;
            return fetch_admin[0];
        } catch (error) {
            throw error
        }
    }

    async vendor_check(payload: any) {
        try {

            let { _id, scope } = payload;
            let query = { _id: new Types.ObjectId(_id), status: UserStatus.ACTIVE  }
            let fetch_user: any = await this.model.UserModel.findOne(query)
            if (!fetch_user) throw new HttpException("Unauthorized", HttpStatus.UNAUTHORIZED)
            fetch_user.scope = scope;
            return fetch_user
        }
        catch (error) {
            throw error
        }
    }


    async verify_token(token: string,) {
        try {
            if (!token) {
                throw new HttpException('token not received', HttpStatus.UNAUTHORIZED);
            } else {
                try {
                    const payload = await this.jwtservice.verifyAsync(token);
                    // console.log("payload",payload);

                    let { scope } = payload;
                    if (scope == this.admin_scope) {
                        let data: any = await this.verifyToken(payload);
                        if (data) {
                            let user_data = await this.admin_check1(
                                payload
                            );
                            return user_data;
                        } else {
                            throw new HttpException('admin not found', HttpStatus.UNAUTHORIZED);
                        }
                    }
                } catch (err) {
                    throw err;
                }
            }
        } catch (error) {
            throw error
        }
    }

    async admin_check1(payload: any) {
        try {
            let { _id, scope } = payload;
            let query = { _id: _id }

            let fetch_admin: any = await this.model.UserModel.findOne(query, {}, { lean: true })
            if (!fetch_admin) {
                throw new UnauthorizedException();
            }
            fetch_admin.scope = scope;
            return fetch_admin;
        } catch (error) {
            throw error
        }
    }

}
