export const analytics = [
    {
        id: 'analyticsLog',
        name: 'Analytics Log',
        description: 'Endpoint for logging analytics data',
        method: 'POST',
        route: '/v3/api/custom/lambda/analytics/',
        inputs: [
            { name: 'user_id', type: 'body', rules: 'required', dataType: 'String' },
            { name: 'session_id', type: 'body', rules: '', dataType: 'String' },
            { name: 'status', type: 'body', rules: 'required', dataType: 'String' },
            { name: 'user_agent', type: 'body', rules: '', dataType: 'String' },
            { name: 'application', type: 'body', rules: '', dataType: 'String' },
            { name: 'document', type: 'body', rules: '', dataType: 'String' },
            { name: 'url', type: 'body', rules: '', dataType: 'Array' },
            { name: 'link_clicks', type: 'body', rules: '', dataType: 'Number' },
            { name: 'clicked_buttons', type: 'body', rules: '', dataType: 'Array' },
            { name: 'client_ip', type: 'body', rules: '', dataType: 'String' },
            { name: 'events', type: 'body', rules: '', dataType: 'Array' },
            { name: 'total_time', type: 'body', rules: '', dataType: 'Number' },
            { name: 'data', type: 'body', rules: '', dataType: 'Object' }
        ],
        response: [
            { id: 'error', key: 'error', value: 'false', valueType: 'Boolean', parent: '' },
            { id: 'message', key: 'message', value: 'Added successfully', valueType: 'String', parent: '' }
        ],
        code: `
        app.post("/v3/api/custom/lambda/analytics/", middlewares, async function (req, res) {
            try {
              let sdk = req.app.get("sdk");
              sdk.setProjectId(req.projectId);
              sdk.setTable("analytics");
              // type: 'pageview',
              // url: [window.location.href,],
              // referrer: document.referrer,
              // userAgent: navigator.userAgent,
              // totalTime,
              // clickCount,
              // buttonClicks,
              // linkClickCount,
              // keypressCount,
              // scrollCount,
              // events,
              // ip,
              // latitude,
              // longitude,
        
              let analytics = await sdk.insert({
                user_id: req.body.user_id,
                session_id: req.body.session_id ? req.body.session_id : null,
                status: req.body.status,
                user_agent: req.body.user_agent ? req.body.user_agent : req.headers["user-agent"],
                application: req.body.application ? req.body.application : '',
                document: req.body.document ? req.body.document : '',
                clicked_links: req.body.url? JSON.stringify(req.body.url) : '',
                link_clicks: req.body.link_clicks? req.body.link_clicks : '',
                clicked_buttons: req.body.clicked_buttons ? JSON.stringify(req.body.clicked_buttons) : '',
                client_ip: req.body.client_ip ? req.body.client_ip : req.ip,
                events: req.body.events ? JSON.stringify(req.body.events) : '',
                response_time: req.body.total_time ? req.body.total_time : 0,
                time_id: req.body.total_time ? sqlDateTimeFormat(new Date(req.body.total_time)) : sqlDateTimeFormat(new Date()),
                data: req.body.data ? JSON.stringify(req.body.data) : '{}',
                create_at: sqlDateTimeFormat(new Date()),
                update_at: sqlDateTimeFormat(new Date()),
              });
        
              // user_id
              // session_id
              // status
              // user_agent
              // application
              // document
              // url
              // link_clicks(count)
              // referrer
              // clicked_buttons
              // url
              // keypress_count,
              // scroll_count,
              // button_clicks
              // client_ip:
              // events
              // response_time
              // total_time
              // data
              return res.status(200).json({
                error: false,
                message: "Added successfully",
              })
        
            } catch (error) {
              console.log(error);
              return res.status(403).json({
                error: true,
                message: "Something went wrong",
              });
            }
          });

        `,
        doc: '',
        unit: '',
        protected: false,
        authorizedRoles: [],
        imports: ``,
        type: 'lambda',
        group: 'analytics'
    },
    {
        id: 'analyticsEndpoint',
        name: 'Get Analytics',
        description: 'Endpoint for getting analytics data',
        method: 'GET',
        route: '/v3/api/custom/lambda/analytics/data',
        inputs: [],
        response: [
            { id: 'error', key: 'error', value: 'false', valueType: 'Boolean', parent: '' },
            { id: 'user_analytics', key: 'model.user_analytics', value: '', valueType: 'Object', parent: 'model' },
            { id: 'guest_analytics', key: 'model.guest_analytics', value: '', valueType: 'Object', parent: 'model' },
            { id: 'click_analytics', key: 'model.click_analytics', value: '', valueType: 'Object', parent: 'model' }
        ],
        code: `

        app.get("/v3/api/custom/lambda/analytics/data", middlewares, async function (req, res) {
            try {
              let sdk = req.app.get("sdk");
              const db = await sdk.getDatabase();
              sdk.setProjectId(req.projectId);
              let {custom_date} = req.query;
              if(!custom_date) custom_date = "7";
              let number_of_days = custom_date === "7" ? 7 : custom_date === "90" ? 90 : custom_date === "14" ? 14 : custom_date === "30" ? 30 : JSON.parse(custom_date);
              console.log(number_of_days,custom_date === "90");
              let {start,end} = formatTime(new Date(), number_of_days);
              let user_sql = \`SELECT COUNT(DISTINCT \${req.projectId}_analytics.user_id) as users FROM \${req.projectId}_analytics WHERE \${req.projectId}_analytics.create_at >= "\${start}" AND \${req.projectId}_analytics.create_at <= "\${end}"\`
              let guests_sql = \`SELECT COUNT(*) as guests FROM \${req.projectId}_analytics WHERE \${req.projectId}_analytics.status="guest" AND \${req.projectId}_analytics.create_at >= "\${start}" AND \${req.projectId}_analytics.create_at <= "\${end}"\`
              let pages = \`SELECT \${req.projectId}_analytics.clicked_links, \${req.projectId}_analytics.clicked_buttons, \${req.projectId}_analytics.link_clicks, \${req.projectId}_analytics.create_at AS date FROM \${req.projectId}_analytics WHERE \${req.projectId}_analytics.create_at >= "\${start}" AND \${req.projectId}_analytics.create_at <= "\${end}"\`
              // sdk.setTable("analytics");
              let userAnalytics = await db.query(user_sql)
              let guestAnalytics = await db.query(guests_sql)
              let clickAnalytics = await db.query(pages)
        
              return res.status(200).json({
                error: false,
                model: {
                  user_analytics: userAnalytics[0],
                  guest_analytics: guestAnalytics[0],
                  click_analytics: clickAnalytics[0],
                }
              })
        
            } catch (error) {
              console.log(error);
              return res.status(403).json({
                error: true,
                message: "Something went wrong",
              });
            }
          });

        `,
        doc: '',
        unit: '',
        protected: false,
        authorizedRoles: [],
        imports: ``,
        type: 'lambda',
        group: 'analytics'
    },
    {
        id: 'heatmapAnalytics',
        name: 'Log Heatmap Analytics',
        description: 'Endpoint for logging heatmap data',
        method: 'POST',
        route: '/v3/api/custom/lambda/heatmap',
        inputs: [
            { name: 'user_id', type: 'body', rules: 'required', dataType: 'String' },
            { name: 'session_id', type: 'body', rules: '', dataType: 'String' },
            { name: 'user_agent', type: 'body', rules: '', dataType: 'String' },
            { name: 'scroll_position', type: 'body', rules: 'required', dataType: 'Object' },
            { name: 'coordinates', type: 'body', rules: 'required', dataType: 'Object' },
            { name: 'status', type: 'body', rules: '', dataType: 'String' },
            { name: 'client_ip', type: 'body', rules: '', dataType: 'String' },
            { name: 'screen_size', type: 'body', rules: '', dataType: 'Number' },
            { name: 'screen_width', type: 'body', rules: '', dataType: 'Number' },
            { name: 'page', type: 'body', rules: '', dataType: 'String' },
            { name: 'screen_height', type: 'body', rules: '', dataType: 'Number' },
            { name: 'snapshot', type: 'body', rules: '', dataType: 'String' },
            { name: 'total_time', type: 'body', rules: '', dataType: 'Number' },
            { name: 'data', type: 'body', rules: '', dataType: 'Object' }
        ],
        response: [
            { id: 'error', key: 'error', value: 'false', valueType: 'Boolean', parent: '' },
            { id: 'message', key: 'message', value: 'Added successfully', valueType: 'String', parent: '' }
        ],
        code: `

        app.post("/v3/api/custom/lambda/heatmap", middlewares, async function (req, res) {
            try {
              let sdk = req.app.get("sdk");
              sdk.setProjectId(req.projectId);
              sdk.setTable("heatmap");
              const {scroll_position,coordinates} = req.body;
        
              if(scroll_position === null || scroll_position === '' ){
                return res.status(403).json({
                  error: true,
                  message: "scroll_position is required",
                })
              }
              if(Object.keys(scroll_position).length <= 1){
                return res.status(403).json({
                  error: true,
                  message: "scroll_position x and y is required",
                })
              }
        
              if(coordinates === null || coordinates === '' ){
                return res.status(403).json({
                  error: true,
                  message: "coordinates is required",
                })
              }
        
              if(Object.keys(coordinates).length <= 1){
                return res.status(403).json({
                  error: true,
                  message: "coordinates x and y is required",
                })
              }
        
              
        
              let data = await sdk.insert({
                user_id: req.body.user_id,
                session_id: req.body.session_id ? req.body.session_id : null,
                user_agent: req.body.user_agent ? req.body.user_agent : req.headers["user-agent"],
                status: req.body.status ? req.body.status : req.body.user_id > 0 ? "user" : "guest",
                client_ip: req.ip ? req.ip : 'na',
                scroll_position_y: req.body.scroll_position ? req.body.scroll_position.scroll_position_y : 0,
                scroll_position_x: req.body.scroll_position ? req.body.scroll_position.scroll_position_x : 0,
                coordinate_x: req.body.coordinates ? req.body.coordinates.coordinate_x : 0,
                coordinate_y: req.body.coordinates ? req.body.coordinates.coordinate_y : 0,
                screen_size: req.body.screen_size ? req.body.screen_size : 0,
                screen_width: req.body.screen_width ? req.body.screen_width : 1440,
                page: req.body.page ? req.body.page : '/',
                screen_height: req.body.screen_height ? req.body.screen_height : 900,
                snapshot: req.body.snapshot ? req.body.snapshot : null,
                response_time: req.body.total_time ? req.body.total_time : 0,
                time_id: req.body.total_time ? sqlDateTimeFormat(new Date(req.body.total_time)) : sqlDateTimeFormat(new Date()),
                data: req.body.data ? JSON.stringify(req.body.data) : '{}',
                create_at: sqlDateTimeFormat(new Date()),
                update_at: sqlDateTimeFormat(new Date()),
              });
        
              return res.status(200).json({
                error: false,
                message: "Added successfully",
              })
        
            } catch (error) {
              console.log(error);
              return res.status(403).json({
                error: true,
                message: "Something went wrong",
              });
            }
          });
        
        
        `,
        doc: '',
        unit: '',
        protected: false,
        authorizedRoles: [],
        imports: '',
        type: 'lambda',
        group: 'analytics'
    },
    {
        id: "heatmapDataEndpoint",
        name: "Get Heatmap Data ",
        description: "Endpoint for retrieving heatmap data",
        method: "GET",
        route: "/v3/api/custom/lambda/heatmap/data",
        inputs: [
            {
                name: "custom_date",
                type: "query",
                rules: "",
                dataType: "String"
            }
        ],
        response: [
            {
                id: "error",
                key: "error",
                value: "false",
                valueType: "Boolean",
                parent: ""
            },
            {
                id: "model",
                key: "model",
                value: "false",
                valueType: "Object",
                parent: ""
            },
            {
                id: "user_analytics",
                key: "user_analytics",
                value: "",
                valueType: "Object",
                parent: "model"
            },
            {
                id: "guest_analytics",
                key: "guest_analytics",
                value: "",
                valueType: "Object",
                parent: "model"
            },
            {
                id: "heat_map_data",
                key: "heat_map_data",
                value: "",
                valueType: "Array",
                parent: "model"
            }
        ],
        code: `

        app.get("/v3/api/custom/lambda/heatmap/data", middlewares, async function (req, res) {
            try {
              let sdk = req.app.get("sdk");
              const db = await sdk.getDatabase();
              sdk.setProjectId(req.projectId);
              let {custom_date} = req.query;
              if(!custom_date) custom_date = "7";
              let number_of_days = custom_date === "7" ? 7 : custom_date === "90" ? 90 : custom_date === "14" ? 14 : custom_date === "30" ? 30 : JSON.parse(custom_date);
              console.log(number_of_days,custom_date === "90");
              let {start,end} = formatTime(new Date(), number_of_days);
              let user_sql = \`SELECT COUNT(DISTINCT \${req.projectId}_heatmap.user_id) as users FROM \${req.projectId}_heatmap WHERE \${req.projectId}_heatmap.create_at >= "\${start}" AND \${req.projectId}_heatmap.create_at <= "\${end}"\`
              let guests_sql = \`SELECT COUNT(*) as guests FROM \${req.projectId}_heatmap WHERE \${req.projectId}_heatmap.status="guest" AND \${req.projectId}_heatmap.create_at >= "\${start}" AND \${req.projectId}_heatmap.create_at <= "\${end}"\`
                
              let pages = \`SELECT 
                          \${req.projectId}_heatmap.page,
                          \${req.projectId}_heatmap.snapshot,
                          \${req.projectId}_heatmap.scroll_position_y, 
                          \${req.projectId}_heatmap.scroll_position_x,
                          \${req.projectId}_heatmap.coordinate_y,
                          \${req.projectId}_heatmap.coordinate_x, 
                          \${req.projectId}_heatmap.screen_size,
                          \${req.projectId}_heatmap.screen_width,
                          \${req.projectId}_heatmap.screen_height,
                          \${req.projectId}_heatmap.create_at AS date FROM \${req.projectId}_heatmap
                          WHERE \${req.projectId}_heatmap.create_at >= "\${start}" AND \${req.projectId}_heatmap.create_at <= "\${end}"\`
              // sdk.setTable("analytics");
              let userAnalytics = await db.query(user_sql)
              let guestAnalytics = await db.query(guests_sql)
              let heatMapData = await db.query(pages)
              let heatMapDataArray = [];
              // {
              //   page:[{page,data,snapshot}]
              // }
              if(heatMapData[0].length > 0){
                heatMapData[0].forEach((key, index) => {
                  const found = heatMapDataArray.find(element =>{
                    return element.page === key.page
                  })
                  if(found){
                    let position = heatMapDataArray.indexOf(found);
                    heatMapDataArray.splice(position, 1)
                    let snap = key
                    delete snap.snapshot
                    delete snap.page
                    snap.count = 1
                    found.data = [...found.data, snap]
                    heatMapDataArray.push(found)
                  } else {
                    let snap = key
                    let snapshot = snap.snapshot
                    delete snap.snapshot
                    let object = {}
                    object.page = key.page
                    snap.count = 1
                    object.data = [snap]
                    delete snap.page
                    object.snapshot = snapshot
                    heatMapDataArray.push(object)
                  }
                })
              }
              console.log(heatMapDataArray);
              let newArray = [];
              const totalArray = [];
              heatMapDataArray.forEach((main, index) => {
                main.data.forEach((key, index) => {
                  if(newArray.find(element => element.coordinate_y === key.coordinate_y)){
                    let position = newArray.indexOf(newArray.find(element => element.coordinate_y === key.coordinate_y));
                    const found = newArray[position]
                    if(found.coordinate_x === key.coordinate_x){
                      newArray.splice(position, 1)
                      if(found.count !== null && found.count !== undefined){
                        found.count++
                      }
                      newArray.push(found)
                    }
                  }else{
                    if(key.count){
                      key.count ++
                    }
                    newArray.push(key)
                  }
                })
                totalArray.push({
                  page: main.page,
                  data: newArray,
                  snapshot: main.snapshot
                })
                  newArray = [];
              })
           
        
              return res.status(200).json({
                error: false,
                model: {
                  user_analytics: userAnalytics[0],
                  guest_analytics: guestAnalytics[0],
                  heat_map_data: totalArray
                }
              })
        
            } catch (error) {
              console.log(error);
              return res.status(403).json({
                error: true,
                message: "Something went wrong",
              });
            }
          });
        
        `,
        doc: "",
        unit: "",
        protected: false,
        authorizedRoles: [],
        imports: "",
        type: "lambda",
        group: "analytics"
    },
    {
        id: "userSessionsDataEndpoint",
        name: "User Sessions Data",
        description: "Endpoint for retrieving user session data",
        method: "GET",
        route: "/v3/api/custom/lambda/user-sessions/data",
        inputs: [
          {
            name: "custom_date",
            type: "query",
            rules: "",
            dataType: "String"
          }
        ],
        response: [
          {
            id: "error",
            key: "error",
            value: "false",
            valueType: "Boolean",
            parent: ""
          },
          {
            id: "model",
            key: "model",
            value: "false",
            valueType: "Object",
            parent: ""
          },
          {
            id: "user_analytics",
            key: "user_analytics",
            value: "",
            valueType: "Object",
            parent: "model"
          },
          {
            id: "guest_analytics",
            key: "guest_analytics",
            value: "",
            valueType: "Object",
            parent: "model"
          },
          {
            id: "heat_map_data",
            key: "heat_map_data",
            value: "",
            valueType: "Array",
            parent: "model"
          }
        ],
        code: `
        
        app.get("/v3/api/custom/lambda/user-sessions/data", middlewares, async function (req, res) {
            try {
              let sdk = req.app.get("sdk");
              const db = await sdk.getDatabase();
              sdk.setProjectId(req.projectId);
              let {custom_date} = req.query;
              if(!custom_date) custom_date = "7";
              let number_of_days = custom_date === "7" ? 7 : custom_date === "90" ? 90 : custom_date === "14" ? 14 : custom_date === "30" ? 30 : JSON.parse(custom_date);
              console.log(number_of_days,custom_date === "90");
              let {start,end} = formatTime(new Date(), number_of_days);
              let user_sql = \`SELECT COUNT(DISTINCT \${req.projectId}_user_sessions.user_id) as users FROM \${req.projectId}_user_sessions WHERE \${req.projectId}_user_sessions.create_at >= "\${start}" AND \${req.projectId}_user_sessions.create_at <= "\${end}"\`
              let guests_sql = \`SELECT COUNT(*) as guests FROM \${req.projectId}_user_sessions WHERE \${req.projectId}_user_sessions.status="guest" AND \${req.projectId}_user_sessions.create_at >= "\${start}" AND \${req.projectId}_user_sessions.create_at <= "\${end}"\`
        
              let pages = \`SELECT 
                          \${req.projectId}_user_sessions.html_copy,
                          \${req.projectId}_user_sessions.events,
                          \${req.projectId}_user_sessions.screen_size,
                          \${req.projectId}_user_sessions.screen_height,
                          \${req.projectId}_user_sessions.screen_width,
                          \${req.projectId}_user_sessions.start_time,
                          \${req.projectId}_user_sessions.end_time,
                          \${req.projectId}_user_sessions.create_at AS date FROM \${req.projectId}_user_sessions
                          WHERE \${req.projectId}_user_sessions.create_at >= "\${start}" AND \${req.projectId}_user_sessions.create_at <= "\${end}"\`
              // sdk.setTable("analytics");
              let userAnalytics = await db.query(user_sql)
              let guestAnalytics = await db.query(guests_sql)
              let sessionData = await db.query(pages)
        
              return res.status(200).json({
                error: false,
                model: {
                  user_analytics: userAnalytics[0],
                  guest_analytics: guestAnalytics[0],
                  heat_map_data: sessionData[0]
                }
              })
        
            } catch (error) {
              console.log(error);
              return res.status(403).json({
                error: true,
                message: "Something went wrong",
              });
            }
          });
        
        `,
        doc: "",
        unit: "",
        protected: false,
        authorizedRoles: [],
        imports: "",
        type: "lambda",
        group: "analytics"
      },
      {
        id: "userSessionsAnalytics",
        name: "Create User Sessions Analytics",
        description: "Endpoint for creating user sessions analytics",
        method: "POST",
        route: "/v3/api/custom/lambda/analytics/user-sessions/",
        inputs: [
          {
            name: "user_id",
            type: "body",
            rules: "",
            dataType: "Integer"
          },
          {
            name: "session_id",
            type: "body",
            rules: "",
            dataType: "Integer"
          },
          {
            name: "status",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "events",
            type: "body",
            rules: "",
            dataType: "Array"
          },
          {
            name: "screen_width",
            type: "body",
            rules: "",
            dataType: "Integer"
          },
          {
            name: "screen_height",
            type: "body",
            rules: "",
            dataType: "Integer"
          },
          {
            name: "screen_size",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "start_time",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "end_time",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "html_copy",
            type: "body",
            rules: "",
            dataType: "String"
          }
        ],
        response: [
          {
            id: "error",
            key: "error",
            value: "false",
            valueType: "Boolean",
            parent: ""
          },
          {
            id: "message",
            key: "message",
            value: "User session created successfully",
            valueType: "String",
            parent: ""
          }
        ],
        code: `
        
        app.post("/v3/api/custom/lambda/analytics/user-sessions/", middlewares, async function (req, res) {
            try {
              let sdk = req.app.get("sdk");
              sdk.setProjectId(req.projectId);
        
              let {
                user_id,
                session_id,
                status,
                events,
                screen_width,
                screen_height,
                screen_size,
                start_time,
                end_time,
                html_copy
              } = req.body;
              if(!stringChecker.isStringNonEmpty([events, screen_width, screen_height, screen_size, start_time, html_copy])){
                return res.status(403).json({
                  error: true,
                  message: "Please provide all the required fields",
                });
              }
        
        
             sdk.setTable("user_sessions");
             await sdk.insert({
                user_id: user_id ? user_id : 0,
                session_id: session_id ? session_id : 0,
                status: user_id > 0 ? 'user' : 'guest',
                events: events ? JSON.stringify(events) : null,
                screen_width: screen_width ? screen_width : 1440,
                screen_height: screen_height ? screen_height : 900,
                screen_size: screen_size ? screen_size : null,
                start_time: start_time ? start_time : Date.now(),
                end_time: end_time ? end_time : Date.now(),
                user_agent: req.headers['user-agent'],
                client_ip: req.ip,
                html_copy: html_copy ? html_copy : null,
                update_at: sqlDateTimeFormat(new Date()),
                create_at: sqlDateTimeFormat(new Date()),
             })
        
              return res.status(200).json({
                error: false,
                message: "User session created successfully",
              })
            } catch (error) {
              console.log(error);
              return res.status(403).json({
                error: true,
                message: "Something went wrong ->" + error.message,
              });
            }
          });

        `,
        doc: "",
        unit: "",
        protected: false,
        authorizedRoles: [],
        imports: "",
        type: "lambda",
        group: "analytics"
      }
      
      

]

export const analyticsImports = `


    const ProjectMiddleware = require("../../../middleware/ProjectMiddleware");
    const UrlMiddleware = require("../../../middleware/UrlMiddleware");
    const HostMiddleware = require("../../../middleware/HostMiddleware");
    const TokenMiddleware = require("../../../middleware/TokenMiddleware");
    const { sqlDateTimeFormat, formatTime } = require("../../../services/UtilService");
    const rateLimit = require("express-rate-limit");
    const { stringChecker } = require("../../../utils/helpers");

    const RateLimitMiddleware = rateLimit({
        windowMs: 2 * 60 * 1000, // 2 minutes
        max: 100, // Limit each IP to 5 requests per window (here, per hour)
        standardHeaders: true, // Return rate limit info in the RateLimit-* headers
        legacyHeaders: false, // Disable the X-RateLimit-* headers
    });

    const middlewares = [
        ProjectMiddleware, 
        // UrlMiddleware, 
        // HostMiddleware,
        RateLimitMiddleware
    ];

    const config = require("../../../config");



`