import {
    BadRequestException,
    HttpException,
    HttpStatus,
    Injectable,
    UnauthorizedException,
} from '@nestjs/common';
// import { ModelService } from 'src/model/model.service';

import { ConfigService } from '@nestjs/config';
import * as dto from './dto/index';
import * as bcrypt from 'bcrypt';
import { toUSVString, types } from 'util';
import { Types } from 'mongoose';
import * as random_string from 'randomstring';
import { count, error, log } from 'console';
import { ModelService } from '../model/model.service';
import { CommonService } from '../common/common.service';
import moment from 'moment';
import { Pinecone } from '@pinecone-database/pinecone'
import * as path from "path";
import * as fs from "fs";
import { workspace_aggregation } from './aggregation/workspace.aggregation'
import { content_type } from './dto/admin.dto';
import { subscription_aggregation } from './aggregation/subscription.aggregation';
import { UserRole } from '../model/schema/user.schema';

@Injectable()
export class AdminService {
    private admin_scope

    constructor(
        private readonly Model: ModelService,
        private readonly ConfigService: ConfigService,
        private readonly CommonService: CommonService // private readonly EmailService: EmailService
    ) {
        this.admin_scope = this.ConfigService.get<string>('ADMIN_SCOPE');

    }

    login = async (dto: dto.admin.Login) => {
        try {
            let { email, password } = dto;
            // ! check email exists
            // let admin = await this.Model.UserModel.find({ email: email.toLowerCase(), super_admin: true });
            const admin = await this.Model.UserModel.find({
                email: email.toLowerCase(),
                $or: [
                    { type: "ADMIN" },
                    { type: "STAFF" }
                ]
            });

            if (admin.length) {
                return await this.login_exisitng_admin(admin[0], dto);
            } else {
                return await this.create_new_admin(dto);
            }
        } catch (err) {
            throw err;
        }
    };

    login_exisitng_admin = async (admin: any, body: dto.admin.Login) => {
        try {
            let { _id, password: hash } = admin;
            let { password } = body;
            // console.log(hash, password);

            let decode = await bcrypt.compare(password, hash);
            // console.log(`🚀 ~ file: admin.service.ts:23 ~ AdminService ~ login ~ decode:`, decode)
            if (decode != true) {
                throw new HttpException('Wrong password', HttpStatus.BAD_REQUEST);
            } else {
                // ! update admin
                let query = { _id: _id };
                let update = { updated_at: +new Date() };
                let options = {
                    projection: {
                        name: 1,
                        profile_pic: 1,
                        email: 1,
                        super_admin: 1,
                        roles: 1,
                        updated_at: 1,
                        created_at: 1,
                    },
                    new: true,
                    lean: true,
                };
                let update_admin = await this.Model.UserModel.findOneAndUpdate(
                    query,
                    update,
                    options
                );
                let token_payload = {
                    _id: _id,
                    scope: this.admin_scope,
                    token_gen_at: +new Date(),
                };
                let token = await this.CommonService.generate_token(token_payload);
                let save_session = await this.CommonService.create_admin_session(
                    body,
                    token_payload,
                    token
                );
                update_admin['access_token'] = token;
                // update_admin.message = "Logged in"
                return update_admin;
            }
        } catch (err) {
            throw err;
        }
    };

    create_new_admin = async (body: dto.admin.Login) => {
        try {
            let { email, password } = body;
            if (email.toLowerCase() != 'admin@gmail.com') {
                throw new HttpException(
                    `Please enter valid Email Address`,
                    HttpStatus.BAD_REQUEST
                );
            }
            let hash = await bcrypt.hash('qwerty', 10);
            let data_to_save = {
                // type: "ADMIN",
                name: 'super admin',
                email: 'admin@gmail.com',
                profile_pic: null,
                password: hash,
                super_admin: true,
                created_at: +new Date(),
            };
            let create = await this.Model.UserModel.create(data_to_save);

            let query = { _id: create._id };
            let projection = {
                email: true,
                name: true,
                super_admin: true,
                roles: true,
                profile_pic: true,
                updated_at: true,
                created_at: true,
            };
            let options = { lean: true };
            let find = await this.Model.UserModel.findOne(query, projection, options);
            let token_payload = {
                _id: find._id,
                scope: this.admin_scope,
                token_gen_at: +new Date(),
            };
            let token = await this.CommonService.generate_token(token_payload);
            let save_session = await this.CommonService.create_admin_session(
                body,
                token_payload,
                token
            );
            find['access_token'] = token;
            return find;
        } catch (err) {
            throw err;
        }
    };

    profile_get = async (req: any) => {
        try {
            let { _id: admin_id } = req.user_data

            let admin = await this.Model.UserModel.findOne({ _id: new Types.ObjectId(admin_id) }, { password: 0, }, { lean: true });
            const project = {
                _id: 1,
                name: 1,
                created_by: 1,
                image: 1,
                description: 1,
                created_at: 1,
            }

            const query: any = {
                is_admin_workspace: true,
                is_deleted: false,
            };

            // const workspace: any = await this.Model.WorkspaceModel.findOne(query, project, { lean: true }).populate({ path: "created_by", select: "name title email" });
            // const secret_key = await this.Model.workspaceKeysModel.findOne({ workspace_id: workspace._id, is_delete: false }, { key: 1 }, { lean: true });
            // workspace.key = secret_key.key;
            // admin['workspace'] = workspace || null;
            // return admin
            const workspace: any = await this.Model.WorkspaceModel.findOne(query, project, { lean: true })
                .populate({ path: "created_by", select: "name title email" });

            if (workspace) {
                const secret_key = await this.Model.workspaceKeysModel.findOne(
                    { workspace_id: workspace._id, is_delete: false },
                    { key: 1 },
                    { lean: true }
                );
                workspace.key = secret_key?.key || null;
            }

            admin['workspace'] = workspace || null;
            return admin;
        } catch (err) {
            throw err;
        }
    }

    editProfile = async (body: dto.admin.editProfileAdmin, req: any) => {
        try {
            let { _id: user_id } = req.user_data;
            let { name, profile_pic } = body;
            let query = { _id: user_id };
            let update = {
                ...(name && { name: name.toLowerCase().trim() }),
                ...(profile_pic && { profile_pic: profile_pic }),
            };
            await this.Model.UserModel.findByIdAndUpdate(query, update, { new: true });
            let response = await this.Model.UserModel.findOne(query, { password: 0 }, { lean: true });
            return response;
        } catch (err) {
            throw err;
        }
    };

    changePassword = async (body: dto.admin.adminChangePass, req: any,) => {
        try {
            let { _id } = req.user_data;
            let { old_password, new_password } = body;

            let query = { _id: _id };
            let get_admin: any = await this.Model.UserModel.findOne(query, {}, { lean: true });

            if (get_admin) {
                let { _id, password: hash } = get_admin;
                // let _id = get_admin._id;
                let decrypted_password = await bcrypt.compare(old_password, hash);
                if (!decrypted_password) {
                    // throw new HttpException(
                    //   "Old Password Mismatch",
                    //   HttpStatus.FORBIDDEN
                    // );
                    throw new BadRequestException(`Old Password Mismatch`);
                } else {
                    let hash_password = await bcrypt.hash(new_password, 10);
                    let update = { password: hash_password };
                    await this.Model.UserModel.findOneAndUpdate(query, update, { new: true });
                }
            }
            return "Password Changed Successfully";
        } catch (err) {
            throw err
        }
    };


    get_workpace = async (body: dto.admin.get_workspace, req: any) => {
        try {
            let { _id } = req.user_data;
            let { pagination, limit } = body;
            let query = [
                await workspace_aggregation.match_data(),
                await workspace_aggregation.lookup_owner(),
                await workspace_aggregation.unwind_owner(),
                await workspace_aggregation.find_members(),
                await workspace_aggregation.add_fields(),
                await workspace_aggregation.lookup_subscription(),
                await workspace_aggregation.unwind_subscription(),
                await workspace_aggregation.group_data(),
                await workspace_aggregation.facetData(pagination, limit),
            ]
            let data = await this.Model.WorkspaceModel.aggregate(query)
            return { count: data[0]?.count[0].count || 0, data: data[0]?.data || [] };
        } catch (err) {
            throw err
        }
    };



    get_workpace_detail = async (wokspace_id: string, req: any) => {
        try {
            let query = [
                await workspace_aggregation.match_workspace_data(wokspace_id),
                await workspace_aggregation.lookup_owner(),
                await workspace_aggregation.unwind_owner(),
                await workspace_aggregation.find_members(),
                await workspace_aggregation.add_fields(),
                await workspace_aggregation.lookup_subscription(),
                await workspace_aggregation.unwind_subscription(),
                await workspace_aggregation.project_data(),
            ]

            let data = await this.Model.WorkspaceModel.aggregate(query);
            return data[0] || {}
        } catch (err) {
            throw err
        }
    };

    get_workpace_members = async (wokspace_id: string, body: dto.admin.get_workspace, req: any) => {
        try {
            let { pagination, limit } = body
            let option = await this.CommonService.set_options(pagination, limit)
            let data = await this.Model.AllUserWorkspaceModel.find(
                { workspace_id: new Types.ObjectId(wokspace_id) },
                {},
                option
            ).populate([{ path: 'vendor_id', select: 'name profile_pic' }])
            let count = await this.Model.AllUserWorkspaceModel.countDocuments(
                { workspace_id: new Types.ObjectId(wokspace_id) }
            )
            return { count: count, data: data };
        } catch (err) {
            throw err
        }
    };

    get_workpace_subscription = async (wokspace_id: string, body: dto.admin.get_workspace, req: any) => {
        try {
            const { pagination, limit } = body
            const option = await this.CommonService.set_options(pagination, limit)
            const query = {
                workspace_id: new Types.ObjectId(wokspace_id),
                status: "authenticated"
            }
            const data = await this.Model.subscriptionModel.find(query, {
                _id: true,
                plan_name: true,
                created_at: true,
                is_active: true,
                status: true,
                amount: true
            }, option)
            const count = await this.Model.subscriptionModel.countDocuments(query)


            return { count: count, data: data };
        } catch (err) {
            throw err
        }
    };

    workpace_status_change = async (wokspace_id: string, body: dto.admin.workspace_status, req: any) => {
        try {
            let { status } = body
            let data = await this.Model.WorkspaceModel.findOneAndUpdate(
                { _id: new Types.ObjectId(wokspace_id) },
                {
                    ...(status && { status: status })
                },
                { new: true, lean: true }
            )
            return data;
        } catch (err) {
            throw err
        }
    };

    /**
     * Fetches a list of vendors based on pagination, search, and other filter parameters.
     * 
     * @param body - The request payload that contains filter options such as pagination, limit, and search term.
     * @param req - The request object, which includes user-specific data (e.g., user ID).
     * @returns An object containing the total count of matching vendors and the paginated list of vendor data.
     * 
     * @throws {Error} - If any error occurs during the query or data retrieval process.
     */
    get_vendor = async (body: dto.admin.get_vendor, req: any) => {
        try {
            let { _id } = req.user_data;
            const { pagination, limit, search, status } = body;

            console.log('body', body)
            const result = await this.Model.UserModel.aggregate([
                {
                    $match: {
                        type: UserRole.VENDOR,
                        ...(search && { name: { $regex: search, $options: "i" } }),
                        ...(status && status != 'null' && { status: status })
                    }
                },
                {
                    $lookup: {
                        from: "workspaces",
                        let: { user_id: "$_id" },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ["$$user_id", "$created_by"] },
                                        ]
                                    }
                                }
                            },
                            {
                                $project: {
                                    _id: true,
                                    name: true,
                                    image: true,
                                }
                            }
                        ],
                        as: "workspace"
                    },
                },
                {
                    $project: {
                        _id: true,
                        type: true,
                        name: true,
                        profile_pic: true,
                        status: true,
                        workspace: true,
                        created_at: true,
                    }
                },
                await subscription_aggregation.facetData(pagination, limit),
            ]);

            return {
                data: result?.[0]?.data || [],
                count: result?.[0]?.count?.[0]?.count || 0,
            }
        } catch (err) {
            throw err;
        }
    };

    get_vendor_detail = async (vendor_id: string, req: any) => {
        try {
            let { _id: user_id } = req.user_data;

            const vendor_detail: any = await this.Model.UserModel.findOne(
                { _id: new Types.ObjectId(vendor_id), type: "VENDOR" },
                {
                    _id: true,
                    type: true,
                    name: true,
                    status: true,
                    email: true,
                    phone_no: true,
                    country: true,
                    country_code: true,
                    profile_pic: true,
                },
                { lean: true }
            );

            if (!vendor_detail) throw new HttpException(`Vendor not found! Invalid vendor_id.`, HttpStatus.BAD_REQUEST);

            const workspace_info = await this.Model.AllUserWorkspaceModel.aggregate([
                await subscription_aggregation.match_with_vendor_id(vendor_id),
                await subscription_aggregation.workspace_info_lookup(),
                await subscription_aggregation.workspace_info_unwind(),
                await subscription_aggregation.workspace_info_project(),
                await subscription_aggregation.facet_data_owner_shared(),
            ]);

            vendor_detail.workspace_info = workspace_info[0] || {};
            return vendor_detail

        } catch (err) {
            throw err
        }
    };

    get_vendor_workspace = async (vendor_id: string, req: any) => {
        try {
            let { _id } = req.user_data;
            let workspace: any = await this.Model.AllUserWorkspaceModel.find(
                { vendor_id: new Types.ObjectId(vendor_id) },
                {},
                { lean: true }).populate([{ path: 'workspace_id', populate: [{ path: 'created_by', select: 'name profile_pic' }] }])

            return workspace
        } catch (err) {
            throw err
        }
    }

    vendor_status_change = async (vendor_id: string, body: dto.admin.vendor_status, req: any) => {
        try {
            let { _id } = req.user_data;
            let { status } = body
            await this.Model.UserModel.findOneAndUpdate(
                { _id: new Types.ObjectId(vendor_id) },
                { status: status },
                { new: true })

            let vendor_detail: any = await this.Model.UserModel.findOne(
                { _id: new Types.ObjectId(vendor_id) },
                {
                    _id: true,
                    type: true,
                    name: true,
                    status: true,
                    email: true,
                    phone_no: true,
                    country: true,
                    country_code: true,
                    profile_pic: true,
                    company_name: true,
                    company_logo: true,
                    company_color: true,
                    company_url: true
                },
                { lean: true })
            return vendor_detail
        } catch (err) {
            throw err
        }
    };

    contact_us_list = async (body: dto.admin.pl, req: any) => {
        try {
            let { _id } = req.user_data;
            let { pagination, limit } = body
            let set_option = await this.CommonService.set_options(pagination, limit)
            let data = await this.Model.contactUsModel.find({}, {}, set_option)
            let count = await this.Model.contactUsModel.countDocuments({}, {})
            return {
                count: count,
                data: data,
            }
        } catch (err) {
            throw err
        }
    };

    contact_us_edit = async (contact_us_id: string, body: dto.admin.contact_us_edit, req: any) => {
        try {
            let { _id } = req.user_data;
            let { status } = body
            let data = await this.Model.contactUsModel.findOneAndUpdate(new Types.ObjectId(contact_us_id), { status: status }, { new: true, lean: true })
            return data
        } catch (err) {
            throw err
        }
    };

    contact_us_detail = async (contact_us_id: string, req: any) => {
        try {
            let { _id } = req.user_data;
            let data = await this.Model.contactUsModel.findById(new Types.ObjectId(contact_us_id), {}, { new: true, lean: true })
            return data
        } catch (err) {
            throw err
        }
    };

    contact_us_delete = async (contact_us_id: string, req: any) => {
        try {
            let { _id } = req.user_data;
            let data = await this.Model.contactUsModel.deleteOne({ _id: new Types.ObjectId(contact_us_id) })
            return { message: "Success" }
        } catch (err) {
            throw err
        }
    };

    add_content = async (dto: dto.admin.AddContent) => {
        try {
            let { image_url, title, description, page_url, page_type } = dto;
            let data_to_save: any = {
                title: title,
                created_at: moment().utc().valueOf()
            }

            if (!!image_url) { data_to_save.image_url = image_url }
            if (!!description) { data_to_save.description = description }
            if (!!page_url) { data_to_save.page_url = page_url }
            if (!!page_type) { data_to_save.page_type = page_type }
            let create = await this.Model.contentModel.create(data_to_save)
            return {
                message: "New content has been successfully added.",
                data: create
            }
        }
        catch (err) {
            throw err;
        }
    }

    edit_content = async (dto: dto.admin.EditContent) => {
        try {
            let { _id, image_url, title, description, page_url } = dto;
            let query = { _id: new Types.ObjectId(_id) }
            let data_to_update: any = {
                updated_at: moment().utc().valueOf()
            }
            if (!!image_url) { data_to_update.image_url = image_url }
            if (!!title) { data_to_update.title = title }
            if (!!description) { data_to_update.description = description }
            if (!!page_url) { data_to_update.page_url = page_url }
            let options = { new: true }
            let update = await this.Model.contentModel.findOneAndUpdate(query, data_to_update, options)
            return {
                message: "Content has been successfully updated.",
                data: update
            }
        }
        catch (err) {
            throw err;
        }
    }

    delete_content = async (dto: dto.admin.ContentDetails) => {
        try {
            let { _id } = dto;
            let query = { _id: _id, is_deleted: false };
            let data_to_update = {
                is_deleted: true,
                updated_at: moment().utc().valueOf()
            }
            let options = { new: true }
            await this.Model.contentModel.findOneAndUpdate(query, data_to_update, options);
            return {
                message: "Content has been successfully deleted."
            }
        }
        catch (err) {
            throw err;
        }
    }

    list_content = async () => {
        try {
            const query: any = { is_deleted: false };
            const projection = { __v: 0, is_deconsted: 0 };
            const options = { lean: true };

            const data = await this.Model.contentModel.find(query, projection, options).sort({
                _id: -1
            });

            return {
                message: "Data retrieved successfully.",
                data: data
            }
        }
        catch (err) {
            throw err;
        }
    }

    content_details = async (dto: dto.admin.ContentDetails) => {
        try {
            let { _id } = dto;
            let query = { _id: _id, is_deleted: false };
            let projection = { __v: 0, is_deleted: 0 }
            let options = { lean: true };
            let find = await this.Model.contentModel.find(query, projection, options);
            if (find.length > 0) {
                return {
                    message: "Data retrieved successfully.",
                    data: find[0]
                }
            }
            else {
                return {
                    message: "Data retrieved successfully.",
                    data: {}
                }
            }
        }
        catch (err) {
            throw err;
        }
    }

    accounting_subscription = async (dto: dto.admin.get_accounting) => {
        try {
            const { pagination, limit, search } = dto;
    
            // Get total revenue
            const total_payments = await this.Model.subscriptionModel.aggregate([
                {
                    $match: {
                        status: 'authenticated',
                    }
                },
                {
                    $group: {
                        _id: null,
                        totalAmount: { $sum: "$amount" }
                    }
                }
            ]);
    
            // Aggregation pipeline
            const pipeline: any[] = [
                await subscription_aggregation.match_data(),
                await subscription_aggregation.lookup_vendor(),
                await subscription_aggregation.unwind_vendor(),
                await subscription_aggregation.lookup_workspace_data(),
                await subscription_aggregation.unwind_workspace_data()
            ];
    
            // Apply search filter if provided
            if (search) {
                pipeline.push({
                    $match: {
                        $or: [
                            { "vendor.name": { $regex: search, $options: "i" } },
                            { "workspace.name": { $regex: search, $options: "i" } }
                        ]
                    }
                });
            }
    
            // Continue aggregation
            pipeline.push(
                await subscription_aggregation.group_data(),
                await subscription_aggregation.facetData(pagination, limit)
            );
    
            const result = await this.Model.subscriptionModel.aggregate(pipeline);
    
            return {
                total_revenue: total_payments[0]?.totalAmount || 0,
                data: result?.[0]?.data || [],
                count: result?.[0]?.count?.[0]?.count || 0,
            };
        } catch (error) {
            throw error;
        }
    };
    

    recent_subscription = async (dto: dto.admin.get_subscription) => {
        try {
            const { pagination, limit } = dto;
            const result = await this.Model.subscriptionModel.aggregate([
                await subscription_aggregation.match_data(),
                await subscription_aggregation.lookup_vendor(),
                await subscription_aggregation.unwind_vendor(),
                await subscription_aggregation.group_data(),
                await subscription_aggregation.facetData(pagination, limit),
            ]);

            return {
                data: result?.[0]?.data || [],
                count: result?.[0]?.count?.[0]?.count || 0,
            }
        } catch (error) {
            throw error;
        }
    }

    subscription_plans = async (dto: dto.admin.get_subscription) => {
        try {
            const { pagination, limit } = dto;
            const result = await this.Model.SubscriptionPlan.aggregate([
                await subscription_aggregation.match_is_deleted(false),
                await subscription_aggregation.facetData(pagination, limit),
            ]);

            return {
                data: result?.[0]?.data || [],
                count: result?.[0]?.count?.[0]?.count || 0,
            }
        } catch (error) {
            throw error;
        }
    }

    dashboard_counts = async (dto: dto.admin.DashboardApi) => {
        try {
            const { type } = dto;
            const timeRanges = {
                YEAR: { start: 'year', end: 'year' },
                MONTH: { start: 'month', end: 'month' },
                WEEK: { start: 'week', end: 'week' },
                TODAY: { start: 'day', end: 'day' },
            };

            const range = timeRanges[type] || timeRanges.TODAY;
            const start_time = moment().startOf(range.start).valueOf();
            const end_time = moment().endOf(range.end).valueOf();

            const timeFilter = {
                $and: [
                    { created_at: { $gte: start_time } },
                    { created_at: { $lte: end_time } },
                ],
            };

            const [total_call, total_chat, voice_chat] = await Promise.all([
                this.Model.CallModel.countDocuments({ type: "CALL", ...timeFilter }),
                this.Model.CallModel.countDocuments({ type: "CHAT", ...timeFilter }),
                this.Model.CallModel.countDocuments({ type: "VOICE_CHAT", ...timeFilter }),
            ]);

            const total_vendor = await this.Model.UserModel.countDocuments({ type: "VENDOR", ...timeFilter });
            const total_subscription = await this.Model.subscriptionModel.countDocuments({ status: "authenticated", ...timeFilter });

            const total_payments = await this.Model.subscriptionModel.aggregate([
                {
                    $match: {
                        status: 'authenticated',
                        ...timeFilter
                    }
                },
                {
                    $group: {
                        _id: null,
                        totalAmount: { $sum: "$amount" }
                    }
                }
            ]);

            const total_earning = total_payments[0]?.totalAmount || 0;

            const gpt_spendings = 0.00;
            const deepgram_spendings = 0.00;

            const data = {
                total_call,
                total_chat,
                voice_chat,
                total_vendor,
                total_earning,
                total_subscription,
                total_payments: total_payments[0]?.totalAmount || 0,
                gpt_spendings,
                deepgram_spendings
            }
            return data;
        } catch (error) {
            throw error;
        }
    };

    recent_vendors = async (dto: dto.admin.get_recent_vendor) => {
        try {
            const { pagination, limit } = dto;
            const result = await this.Model.UserModel.aggregate([
                {
                    $match: { type: UserRole.VENDOR }
                },
                {
                    $lookup: {
                        from: "workspaces",
                        let: { user_id: "$_id" },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $and: [
                                            { $eq: ["$$user_id", "$created_by"] },
                                        ]
                                    }
                                }
                            },
                            {
                                $project: {
                                    _id: true,
                                    name: true,
                                    image: true,
                                }
                            }
                        ],
                        as: "workspace"
                    },
                },
                {
                    $project: {
                        _id: true,
                        type: true,
                        name: true,
                        profile_pic: true,
                        status: true,
                        workspace: true,
                        created_at: true,
                    }
                },
                await subscription_aggregation.facetData(pagination, limit),
            ]);

            return {
                data: result?.[0]?.data || [],
                count: result?.[0]?.count?.[0]?.count || 0,
            }
        } catch (error) {
            throw error;
        }
    }

    /**
     * Retrieves a paginated list of white labels based on the provided search criteria.
     */
    white_label_list = async (dto: dto.admin.get_white_label_list) => {
        try {
            const { pagination, limit, search } = dto;
            const options = await this.CommonService.set_options(pagination, limit);

            let query = {};
            if (search) {
                query = {
                    $or: [
                        { name: { $regex: search, $options: "i" } },
                        { email: { $regex: search, $options: "i" } },
                        { message: { $regex: search, $options: "i" } },
                    ]
                };
            }

            const [data, count] = await Promise.all([
                this.Model.WhiteLableModel.find(query, {}, options).populate('user', 'name email profile_pic'),
                this.Model.WhiteLableModel.countDocuments(query)
            ]);

            return { count, data };
        } catch (error) {
            console.error('Error fetching white label list:', error);
            throw error;
        }
    };


    create_workspace = async (req: any, body: dto.admin.workspace_create) => {
        try {
            const { _id: user_id } = req.user_data;
            const { name, image, description, secret_key } = body;
            const index_name = name.toLowerCase();

            const createWorkspace = async () => {
                const newWorkspace = await this.Model.WorkspaceModel.create({
                    index_name,
                    name,
                    title: name,
                    description,
                    created_by: new Types.ObjectId(user_id),
                    image,
                    is_admin_workspace: true
                });

                await this.Model.workspaceKeysModel.create({ workspace_id: newWorkspace._id, key: secret_key })

                return newWorkspace;
            };

            // Check if workspace name already exists
            const existingWorkspace = await this.Model.WorkspaceModel.findOne({ is_admin_workspace: true, is_deleted: false });
            if (existingWorkspace) {
                throw new HttpException(
                    `A workspace already exists.`,
                    HttpStatus.BAD_REQUEST
                );
            }

            return createWorkspace();
        } catch (error) {
            throw error;
        }
    }

    get_admin_workspace = async (req: any) => {
        try {
            const query: any = {
                is_admin_workspace: true,
                is_deleted: false,
            };

            const project = {
                _id: 1,
                name: 1,
                created_by: 1,
                image: 1,
                description: 1,
                created_at: 1,
            }
            const workspace = await this.Model.WorkspaceModel.findOne(query, project, { lean: true }).populate({ path: "created_by", select: "name title email" });
            const secret_key = await this.Model.workspaceKeysModel.findOne({ workspace_id: workspace._id, is_delete: false }, { key: 1 }, { lean: true });
            workspace['secret_key'] = secret_key.key;

            return workspace ?? null;
        } catch (error) {
            console.error('Error fetching admin workspace:', error.message);
            throw new Error(`Failed to fetch admin workspace: ${error.message}`);
        }
    };

    get_secret_key = async (key: string) => {
        try {
            if (key) {
                let data = await this.Model.workspaceKeysModel.findOne({ key: key?.toLowerCase() }, {}, { lean: true })
                if (data) {
                    this.get_secret_key(null)
                } else {
                    return key.toLowerCase()
                }
            }
            let count = await this.Model.workspaceKeysModel.countDocuments()
            let gen_key = await this.CommonService.genSecretKey(count)
            console.log("gen_key", gen_key);

            return await this.get_secret_key(gen_key)
        } catch (error) {
            throw error
        }
    }

    async workspace_script_create(workspace_id: string, body: dto.admin.workspace_script_create, req: any) {
        try {
            const { _id: user_id } = req.user_data;
            const { agent_id, key, image, title, description, colour, font_colour } = body;

            const workspace = await this.Model.WorkspaceModel.findOne({ _id: new Types.ObjectId(workspace_id), is_admin_workspace: true, is_deleted: false })
            if (!workspace) throw new HttpException(`You are not in admin workspace! Please create your workspace to proceed.`, HttpStatus.BAD_REQUEST)

            const agent: any = await this.Model.scriptModel.findOne({ agent_id: new Types.ObjectId(agent_id) }).populate({ path: 'agent_id', select: 'name' });
            if (agent) throw new HttpException(`The agent '${agent?.agent_id?.name}' is already assigned to this script. Kindly select a different agent to proceed.`, HttpStatus.BAD_REQUEST);

            const script = await this.Model.scriptModel.create({
                workspace_id: new Types.ObjectId(workspace_id),
                agent_id: new Types.ObjectId(agent_id),
                key: key,
                image: image,
                title: title,
                description: description,
                colour: colour,
                font_colour: font_colour,
            });
            return script
        } catch (error) {
            throw error
        }
    }

    

}
