JB123

import { HttpException, HttpStatus, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { v4 as uuidv4 } from 'uuid';
import UtilService from 'src/common/utility/common.util';
import { ConfigService } from '@nestjs/config';
import { AxiosRequestConfig } from 'axios/index';
import CreateProcessResponse from './model/create-process-response.model';
import CreateProcessRequest from './model/create-process-request.model';
import AxiosUtil from '../applib/util/axios.util';

@Injectable()
export default class ProcessService {
    private agentsConfig: any;

    constructor(
        private readonly axiosUtil: AxiosUtil,
    private http: HttpService,
    private utilService: UtilService,
    private readonly configService: ConfigService,
    ) {
    this.agentsConfig = this.configService.get<any[]>('Agents');
  }

    // public async createProcess(request: CreateProcessRequest): Promise<CreateProcessResponse> {
    //     let test = "test";
    //     return {statusCode:'0000' , statusDescription: 'Success', data: request};
    // }
    getAgentConfig(agentName: string): any {
        return this.agentsConfig.find((agent) => agent.name === agentName);
    }

    storeData(agentName: string, intentName: string, intentData: any): void {
        const agentConfig = this.getAgentConfig(agentName);
        const intent = intentName;

        // TODO Capture the user responses to Intent based
    }

    async callExperienceApi(agentName: string, intentName: string, headers: any, processedData: any): Promise<any> {
        const agentConfig = this.getAgentConfig(agentName);
        const intentConfig = agentConfig.Intents[intentName];
        const apiUrl = intentConfig.serviceUrl;

        const intentHeaders = intentConfig.headers || {};

        headers = { ...intentHeaders, ...headers };

        const headersToExclude = ['content-length', 'host'];
        for (const header of headersToExclude) {
            delete headers[header];
        }

        let payload = { ...intentConfig.request };

        const replacePlaceholders = (obj: any, parent: any = null, keyInParent: any = null, actionData: any = null) => {
            for (const key in obj) {
                if (obj.hasOwnProperty(key)) {
                    const value = obj[key];
                    if (key === 'fillMethod') continue;
                    if (key === 'items') {
                        // Extract intent from placeholder and get actionDataArray
                        const intent = extractIntent(value[0]);
                        const actionDataArray = getActionData(intent, intentName);

                        // Check the fillMethod of the parent object
                        const fillMethod = obj.fillMethod || 'latest';
                        if (fillMethod === 'all') {
                            parent[keyInParent] = actionDataArray.map((actionData) => {
                                let newItem = JSON.parse(JSON.stringify(value[0]));
                                replacePlaceholders(newItem, null, null, actionData);
                                return newItem;
                            });
                        } else {
                            const latestActionData = getLatestActionData(intent, intentName);
                            const newItem = JSON.parse(JSON.stringify(value[0]));
                            replacePlaceholders(newItem, null, null, latestActionData);
                            parent[keyInParent] = [newItem];
                        }
                        continue;
                    }
                    if (typeof value === 'string' && value.startsWith('$')) {
                        const [intent, field] = value.substr(1).split('.');

                        obj[key] = actionData
              ? actionData[field] || null
              : getLatestActionData(intent, intentName)[field] || null;
                    } else if (Array.isArray(value) || typeof value === 'object') {
                        replacePlaceholders(value, obj, key, actionData);
                    }
                }
            }
        };

        const extractIntent = (item: any) => {
            for (const key in item) {
                if (typeof item[key] === "string" && item[key].startsWith("$")) {
                    return item[key].substr(1).split(".")[0];
                } else if (Array.isArray(item[key]) || typeof item[key] === "object") {
                    return extractIntent(item[key]);
                }
            }
        };
        const getActionData = (intent: string,intentName: string) => {
            return processedData[intentName]?.userActions[intent] || processedData[intent]?.userActions[intent] || [];
        };
        const getLatestActionData = (intent: string, intentName: string) => {
            const actionsData = getActionData(intent, intentName);
            if (actionsData.length === 0) {
                return {};
            }
            return actionsData.reduce(
        (prev, current) => (parseInt(prev.seqNum) > parseInt(current.seqNum) ? prev : current),
        {},
      );
        };

        // Replace Placeholders
        replacePlaceholders(payload);

        new Logger().log(payload);

        new Logger().log(headers);
        this.agentsConfig = null;

        return this.postService(headers, apiUrl, payload);
    }


    public async postService(headers: any, URI: string, payload: any): Promise<any> {
        console.log('url', URI);
        let response = null;
        try {
            // response = await this.axiosUtil.getInstance().post(URI, payload, {headers: {
            //   'Content-Type': 'application/json',
            //     'x-experienceId':'03d41404-62e6-448c-a41a-c6a872810702',
            //     'token':'49740c6678e94bcd816f564d57202d1211866605276253'
            // }});
            response = await this.axiosUtil.getInstance().post(URI, payload, { headers });
            return response;
        } catch (error) {
            console.error('Error', error.response?.data, error.message);
            new Logger().log(error.message);
            throw error;
        }
        return response;
    }
}