import express from 'express';
import { Request, Response, NextFunction } from 'express';
import { getRepository, getConnection } from 'typeorm';
import { validationMiddleware, redisMiddleware } from '../middlewares';
import { Global } from "../global";
import * as path from 'path';
import {
  InternalServerErrorException,
  NoDataFoundException,
} from '../exceptions';
import { BlockchainKernel } from '../entities';
import {
  BlockchainKernelCreateDto,
  BlockchainKernelSingleViewDto,
  BlockchainKernelUpdateDto,
  BlockchainKernelPaginationDto,
  TransactionFeeDto,
} from '../dtos';
import { Paginate } from '../utils';
const http = require('http');
const request_promise = require('request-promise');

var moment = require('moment');

export class BlockchainKernelController {
  public path = '/blockchain_kernel';
  public router = express.Router();

  constructor() {
    this.IntializeRoutes();
  }

  IsJsonString(str) {
    try {
     var dataJson = JSON.parse(str);
    } catch (e) {
        return [];
    }
    return dataJson;
  }

  public IntializeRoutes() {
    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel:
     *   post:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     summary: create a blockchain_kernel
     *     description: create a blockchain_kernel
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: BlockchainKernel
     *         description: create a blockchain_kernel
     *         in: body
     *         required: true
     *         schema:
     *           $ref: '#/definitions/BlockchainKernelDto'
     *     responses:
     *       200:
     *         description: blockchain_kernel created successfully
     * definitions:
     *   BlockchainKernelDto:
     *    description: Dto
     *    properties:
     *      Id:
     *           type: integer
     *      Features:
     *           type: string
     *      Fee:
     *           type: integer
     *      LockHeight:
     *           type: integer
     *      Excess:
     *           type: string
     *      ExcessSig:
     *           type: string
     *      Block:
     *           type: string
     */

    this.router.post(
      `${this.path}`,
      validationMiddleware(BlockchainKernelCreateDto),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.BlockchainKernelCreate,
    );

    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel/transactionfee:
     *   get:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     summary: create a blockchain_kernel
     *     description: create a blockchain_kernel
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: FromDate
     *         description: Enter the From date
     *         in: query
     *         type: string
     *       - name: ToDate
     *         description: Enter the To date
     *         in: query
     *         type: string
     *       - name: Interval
     *         description: Try to give Intevals such as 1 week/ 15 days/ 30 days/ 60 days/ 3 months
     *         in: query
     *         type: string
     *     responses:
     *       200:
     *         description: Transaction fee chart fetched successfully
     */
    this.router.get(
      `${this.path}/transactionfee`,
      validationMiddleware(TransactionFeeDto, true),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.TransactionFee,
    );

    /**
     * @swagger
     * /epic_explorer/v1/translator:
     *   get:
     *     tags:
     *       - name: Translator | Translator CONTROLLER
     *     summary: create a translator
     *     description: create a translator
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: lang
     *     responses:
     *       200:
     *         description: Transaction fee chart fetched successfully
     */
    this.router.get(
      `${this.path}/translator`,
      this.Translator,
    );


     /**
     * @swagger
     * /epic_explorer/v1/network:
     *   get:
     *     tags:
     *       - name: Network | Network CONTROLLER
     *     summary: change a network
     *     description: change a network
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: network
     *     responses:
     *       200:
     *         description: Network Changed successfully
     */
    this.router.get(
      `${this.path}/network`,
      this.changeNetwok,
    );

    /**
     * @swagger
     * /epic_explorer/v1/getpeers:
     *   get:
     *     tags:
     *       - name: Translator | Translator CONTROLLER
     *     summary: create a translator
     *     description: create a translator
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: lang
     *     responses:
     *       200:
     *         description: Transaction fee chart fetched successfully
     */
    this.router.get(
      `${this.path}/getpeers`,
      redisMiddleware(60),
      this.getPeers,
    );

    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel/transactionheatmap:
     *   get:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     summary: Transaction Heatmap
     *     description: Transaction Heatmap (Input/output/kernal)
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     responses:
     *       200:
     *         description: Transaction heatmap chart fetched successfully
     */
    this.router.get(
      `${this.path}/transactionheatmap`,
      validationMiddleware(TransactionFeeDto, true),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.HeatmapChart,
    );

    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel/transactionlinechart:
     *   get:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     summary: Transaction line chart
     *     description: Transaction line chart
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: FromDate
     *         description: Enter the From date
     *         in: query
     *         type: string
     *       - name: ToDate
     *         description: Enter the To date
     *         in: query
     *         type: string
     *       - name: Interval
     *         description: Try to give Intevals such as 1 week/ 15 days/ 30 days/ 60 days/ 3 months
     *         in: query
     *         type: string
     *     responses:
     *       200:
     *         description: Transaction line chart fetched successfully
     */
    this.router.get(
      `${this.path}/transactionlinechart`,
      validationMiddleware(TransactionFeeDto, true),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.TransactionChart,
    );

    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel/list:
     *   get:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     description: pagination blockchain_kernel
     *     summary: pagination blockchain_kernel
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: current_page
     *         description: current page specification
     *         in: query
     *         type: integer
     *         required: true
     *       - name: page_size
     *         description: page size specification
     *         in: query
     *         type: integer
     *         required: true
     *       - name: max_pages
     *         description: max pages specification
     *         in: query
     *         type: integer
     *         required: true
     *     responses:
     *       200:
     *         description: blockchain_kernel list fetched successfully
     */
    this.router.get(
      `${this.path}/list`,
      validationMiddleware(BlockchainKernelPaginationDto),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.BlockchainKernelPagination,
    );

    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel/id:
     *   get:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     summary:  get single blockchain_kernel
     *     description: get single blockchain_kernel
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: Id
     *         in: path
     *         description: blockchain_kernel id
     *         required: true
     *         type: string
     *     responses:
     *       200:
     *         description: blockchain_kernel successfully fetched for given id..
     */
    this.router.get(
      `${this.path}/:id`,
      validationMiddleware(BlockchainKernelSingleViewDto),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.BlockchainKernelFetch,
    );

    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel:
     *   patch:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     summary:  update a blockchain_kernel
     *     description:  update a blockchain_kernel
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: blockchain_kernel
     *         description:
     *         in: body
     *         required: true
     *         schema:
     *           $ref: '#/definitions/BlockchainKernelDto'
     *     responses:
     *       200:
     *         description: blockchain_kernel updated successfully
     */
    this.router.patch(
      `${this.path}`,
      validationMiddleware(BlockchainKernelUpdateDto),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.BlockchainKernelUpdate,
    );

    /**
     * @swagger
     * /epic_explorer/v1/blockchain_kernel/id:
     *   delete:
     *     tags:
     *       - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
     *     summary:  delete a blockchain_kernel
     *     description: delete a blockchain_kernel
     *     consumes:
     *       - application/json
     *     produces:
     *       - application/json
     *     parameters:
     *       - name: Id
     *         in: path
     *         description: blockchain_kernel id
     *         required: true
     *         type: string
     *     responses:
     *       200:
     *         description: blockchain_kernel successfully deleted for given id..
     */
    this.router.delete(
      `${this.path}/:id`,
      validationMiddleware(BlockchainKernelSingleViewDto),
      redisMiddleware(process.env.REDIS_EXPIRY),
      this.BlockchainKernelDelete,
    );
  }

  private BlockchainKernelCreate = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const BlockchainKernelRequestData: BlockchainKernelCreateDto =
        request.body;
      const BlockchainKernelCreateQuery = await getConnection(Global.network).getRepository(
        BlockchainKernel,
      ).save(BlockchainKernelRequestData);
      response.status(200).json({
        status: 200,
        timestamp: Date.now(),
        message: 'blockchain_kernel created successfully',
        response: BlockchainKernelCreateQuery,
      });
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private BlockchainKernelFetch = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const BlockchainKernelFetchQuery = await getConnection(Global.network).getRepository(
        BlockchainKernel,
      ).findOne({
        where: { id: request.params.id },
      });
      BlockchainKernelFetchQuery
        ? response.status(200).json({
          status: 200,
          timestamp: Date.now(),
          message: 'blockchain_kernelsuccessfully fetched for given id.',
          response: { ...BlockchainKernelFetchQuery },
        })
        : next(new NoDataFoundException());
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private BlockchainKernelUpdate = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const BlockchainKernelRequestData: BlockchainKernelUpdateDto =
        request.body;
      const BlockchainKernelUpdateQuery = await getConnection(Global.network).getRepository(
        BlockchainKernel,
      ).update(BlockchainKernelRequestData.Id, BlockchainKernelRequestData);
      response.status(200).json({
        status: 200,
        timestamp: Date.now(),
        message: 'blockchain_kernel updated succesfully',
        response: { ...BlockchainKernelUpdateQuery },
      });
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private BlockchainKernelDelete = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const BlockchainKernelDeleteQuery = await getConnection(Global.network).getRepository(
        BlockchainKernel,
      ).delete(request.params.Id);
      BlockchainKernelDeleteQuery
        ? response.status(200).json({
          status: 200,
          timestamp: Date.now(),
          message: 'blockchain_kernel successfully deleted for given id.',
          response: { ...BlockchainKernelDeleteQuery },
        })
        : next(new NoDataFoundException());
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private BlockchainKernelPagination = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const BlockchainKernelRequestData: BlockchainKernelPaginationDto =
        request.query;
      const BlockchainKernelCountQuery = await getConnection(Global.network).getRepository(
        BlockchainKernel,
      ).findAndCount({});
      if (BlockchainKernelCountQuery[1]) {
        const PaginationReponseData = Paginate(
          BlockchainKernelCountQuery[1],
          BlockchainKernelRequestData.CurrentPage,
          BlockchainKernelRequestData.PageSize,
          BlockchainKernelRequestData.MaxPages,
        );
        const BlockchainKernelPaginationQuery = await getConnection(Global.network).getRepository(
          BlockchainKernel,
        ).find({
          skip: PaginationReponseData.startIndex,
          take: PaginationReponseData.pageSize,
          order: {
            Id: 'DESC',
          },
        });
        response.status(200).json({
          status: 200,
          timestamp: Date.now(),
          message: 'blockchain_kernel list fetched successfully',
          response: {
            ...PaginationReponseData,
            ...BlockchainKernelPaginationQuery,
          },
        });
      } else {
        next(new NoDataFoundException());
      }
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private changeNetwok = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      Global.network = request.query.network;
      console.log(Global.network);
      //const network = request.query.network;
      response.status(200).json({
        status: 200,
        timestamp: Date.now(),
        message: 'Network Changed successfully',
        response: request.query.network,
      });
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };
  private Translator = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const lang = request.query.lang;

      /*  response.status(200).json({
          status: 200,
          timestamp: Date.now(),
          message: 'Transaction fee chart fetched successfully',
          response: {
            lang: lang
          },
        }); */
      console.log(path.resolve(__dirname + '/../i18n/' + request.query.lang + '.json'));
      console.log("Without :", path.resolve('/../i18n/' + request.query.lang + '.json'));
      response.header("Content-Type", 'application/json');
      response.sendFile(path.resolve(__dirname + '/../i18n/' + request.query.lang + '.json'));

    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private getPeers = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    var self = this;
    try {
      if(Global.network == "Floonet"){
          var peer_url = process.env.FLOONET_PEER_URL;
      }else{
        var peer_url = process.env.TESTNET_PEER_URL;
      }
      let finalresult = await request_promise(peer_url);
      if(finalresult){
        var jsonresponse = JSON.parse(finalresult);
      }
         let result = jsonresponse.map(function (value, i) {
            value['id'] = i;
            return value;
         });
        response.status(200).json({
        status: 200,
        timestamp: Date.now(),
        message: 'Peers list fetched successfully',
        response: {
        dataJson:  result
        },
      });
      // http.get(peer_url,
      // async (resp) => {
      //   // console.log('resp resp respresp',resp);
      //   let data = '';
      //   let result ;

      //   // A chunk of data has been recieved.
      //   await new Promise((resolve) => {
      //   resp.on('data', function (chunk) {
      //      data += chunk;

      //      let dataJson = self.IsJsonString(data);
      //      if(dataJson.length > 0){

      //     result = dataJson.map(function (value, i) {
      //         value['id'] = i;
      //         return value;
      //      });
      //    }
      //    resolve();
      //    });
      // });
      //   response.status(200).json({
      //     status: 200,
      //     timestamp: Date.now(),
      //     message: 'Peers list fetched successfully',
      //     response: {
      //     dataJson:  result
      //     },
      //   });
      // });
    } catch (error) {
      console.log('error 3###########', error);
      next(new InternalServerErrorException(error));
    }
  };


  private TransactionFee = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const TransactionFeeRequestData: TransactionFeeDto = request.query;
      if (TransactionFeeRequestData.Interval) {
        var timeIntervalQry =
          "timestamp > current_date - interval '" +
          TransactionFeeRequestData.Interval +
          "'";
      } else if (
        TransactionFeeRequestData.FromDate ||
        TransactionFeeRequestData.ToDate
      ) {
        let fromdate = moment(TransactionFeeRequestData.FromDate)
          .utc()
          .format('YYYY-MM-DD');
        let todate = moment(TransactionFeeRequestData.ToDate)
          .utc()
          .format('YYYY-MM-DD');

          var timeIntervalQry =
          "timestamp at time zone '" +
          process.env.TIME_ZONE +
          "' BETWEEN SYMMETRIC '" +
          fromdate +
          "' AND '" +
          todate +
          "'";
      } else {
        var timeIntervalQry = "timestamp > current_date - interval '30 days'";
      }
      const TransactionFeeQuery = await getConnection(Global.network)
        .query(
          "select 1 as hash, date(DATE_TRUNC('day', timestamp)) as date, avg(fee)/1000000000 as fee \
            from blockchain_block t1 join blockchain_kernel t2 on t2.block_id=t1.hash  where fee > 0 and " +
          timeIntervalQry +
          "group by DATE_TRUNC('day', timestamp) order by date",
        )
        .catch(err_msg => {
          next(err_msg);
        });
      let date = [],
        Fee = [];
      TransactionFeeQuery.forEach(e => {
        date.push(moment(e.date).format('YYYY-MM-DD'));
        Fee.push(e.fee);
      });

      if(date.length == 0){
        date = [moment(Date.now()).format('YYYY-MM-DD')];
        Fee = [0];
      }
      response.status(200).json({
        status: 200,
        timestamp: Date.now(),
        message: 'Transaction fee chart fetched successfully',
        response: {
          Date: date,
          Fee: Fee,
        },
      });
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private HeatmapChart = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      // const TransactionFeeRequestData: TransactionFeeDto = request.query;
      // if (TransactionFeeRequestData.Interval) {
      //   var timeIntervalQry =
      //     "timestamp > current_date - interval '" +
      //     TransactionFeeRequestData.Interval +
      //     "'";
      // } else if (
      //   TransactionFeeRequestData.FromDate ||
      //   TransactionFeeRequestData.ToDate
      // ) {
      let fromdate = moment()
        .subtract(7, 'd')
        .format('YYYY-MM-DD');
      let todate = moment()
        .subtract(1, 'd')
        .format('YYYY-MM-DD');

      // var timeIntervalQry =
      //   'timestamp BETWEEN SYMMETRIC ' + fromdate + ' AND ' + todate;
      // } else {
      //   var timeIntervalQry = "timestamp > current_date - interval '30 days'";
      // }
      const TransactionHeatmapChartQuery = await getConnection(Global.network)
        .query(
          "with hours as ( \
            SELECT generate_series('" +
          fromdate +
          " 00:00:00'::timestamp, '" +
          todate +
          " 23:00:00', '1 hours') as hour ) select hours.hour, t1.totalinput, t1.totalkernal, t1.totaloutput \
            from hours left join(select to_char(x.timestamp,'YYYY-MM-DD HH24:00:00') as hour_of_day ,\
                    SUM(x.input_count) as totalinput, SUM(x.kernal_count) as totalkernal, SUM(x.output_count) as totaloutput\
            from ( SELECT blockchain_block.hash, \
              blockchain_block.timestamp, \
              sum(bi.block_id_count)  AS input_count,\
sum(bk.block_id_count) AS kernal_count, \
              sum(bo.block_id_count) AS output_count \
       FROM   blockchain_block \
              LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_input group by block_id) as bi  \
                     ON blockchain_block.hash = \
                        bi.block_id  \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_kernel where features != 'Coinbase' group by block_id) as bk  \
                     ON blockchain_block.hash = \
                        bk.block_id \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_output where output_type != 'Coinbase' group by block_id) as bo \
                     ON blockchain_block.hash = \
                        bo.block_id WHERE blockchain_block.timestamp >= '" +
          fromdate +
          " 00:00:00' \
                          AND blockchain_block.timestamp <= '" +
          todate +
          " 23:59:59' \
       GROUP  BY blockchain_block.hash \
       ORDER  BY blockchain_block.timestamp DESC ) as x \
                group by to_char(x.timestamp,'YYYY-MM-DD HH24:00:00') \
                order by hour_of_day asc) as t1 on to_timestamp(t1.hour_of_day, 'YYYY-MM-DD HH24:00:00') = hours.hour",
        )
        .catch(err_msg => {
          next(err_msg);
        });
      let date = [],
        hour = [],
        totalinput = [],
        totalkernal = [],
        totaloutput = [],
        innerhour = [],
        innertotalinput = [],
        innertotalkernal = [],
        innertotaloutput = [],
        prev_date = '';

      //   for(var i=0 ; i < 7 ; i++){
      //     date.push(moment().subtract(7, 'days').add(i, 'days').format('YYYY-MM-DD'));
      //  }

      TransactionHeatmapChartQuery.forEach(e => {
        var dateformat = moment(e.hour)
          .format('YYYY-MM-DD HH')
          .split(' ');

        if (date.indexOf(dateformat[0]) >= 0 && prev_date == dateformat[0]) {
          innerhour.push(dateformat[1]);
          innertotalinput.push(e.totalinput != null ? e.totalinput : 0);
          innertotalkernal.push(e.totalkernal != null ? e.totalkernal : 0);
          innertotaloutput.push(e.totaloutput != null ? e.totaloutput : 0);
        } else {
          date.push(dateformat[0]);
          innerhour.length > 0 ? hour.push(innerhour) : '';
          innertotalinput.length > 0 ? totalinput.push(innertotalinput) : '';
          innertotalkernal.length > 0 ? totalkernal.push(innertotalkernal) : '';
          innertotaloutput.length > 0 ? totaloutput.push(innertotaloutput) : '';
          (innerhour = []),
            (innertotalinput = []),
            (innertotalkernal = []),
            (innertotaloutput = []);
          innerhour.push(dateformat[1]);
          innertotalinput.push((e.totalinput! = null ? e.totalinput : 0));
          innertotalkernal.push(e.totalkernal != null ? e.totalkernal : 0);
          innertotaloutput.push(e.totaloutput != null ? e.totaloutput : 0);
          prev_date = dateformat[0];
        }
      });
      hour.push(innerhour);
      totalinput.push(innertotalinput);
      totalkernal.push(innertotalkernal);
      totaloutput.push(innertotaloutput);

      response.status(200).json({
        status: 200,
        timestamp: Date.now(),
        message: 'Transaction heatmap chart fetched successfully',
        response: {
          date,
          hour,
          totalinput,
          totalkernal,
          totaloutput,
        },
      });
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };

  private TransactionChart = async (
    request: Request,
    response: Response,
    next: NextFunction,
  ) => {
    try {
      const TransactionFeeRequestData: TransactionFeeDto = request.query;
      if (TransactionFeeRequestData.Interval) {        
        var timeIntervalQry =
          "blockchain_block.timestamp > current_date - interval '" +
          TransactionFeeRequestData.Interval +
          "'";
        var seriesquery =
          "now() - interval '" +
          TransactionFeeRequestData.Interval +
          "', now()";
      } else if (
        TransactionFeeRequestData.FromDate ||
        TransactionFeeRequestData.ToDate
      ) {
        // var timeIntervalQry =
        //   'blockchain_block.timestamp BETWEEN SYMMETRIC ' +
        //   TransactionFeeRequestData.FromDate +
        //   ' AND ' +
        //   TransactionFeeRequestData.ToDate;

          var timeIntervalQry =
          "blockchain_block.timestamp at time zone '" +
          process.env.TIME_ZONE +
          "' BETWEEN SYMMETRIC '" +
          TransactionFeeRequestData.FromDate +
          "' AND '" +
          TransactionFeeRequestData.ToDate +
          "'";
        
        var seriesquery =
          "'" +
          TransactionFeeRequestData.FromDate +
          "'::timestamp, '" +
          TransactionFeeRequestData.ToDate +
          "'";
      } else {
        var timeIntervalQry =
          "blockchain_block.timestamp > current_date - interval '30 days'";
        var seriesquery = "now() - interval '30 days', now()";
      }
      const TransactionHeatmapChartQuery = await getConnection(Global.network)
        .query(
          'with hours as ( SELECT hour::date from generate_series(' +
          seriesquery +
          ", '1 day') as hour) select hours.hour, \
              t1.totalinput, \
              t1.totalkernal, \
              t1.totaloutput \
            from hours left join(select to_char(x.timestamp,'YYYY-MM-DD') as hour_of_day , \
                    SUM(x.input_count) as totalinput, SUM(x.kernal_count) as totalkernal, SUM(x.output_count) as totaloutput \
            from (  SELECT blockchain_block.hash, \
              blockchain_block.timestamp, \
              sum(bi.block_id_count)  AS input_count,\
sum(bk.block_id_count) AS kernal_count, \
              sum(bo.block_id_count) AS output_count \
       FROM   blockchain_block \
              LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_input group by block_id) as bi  \
                     ON blockchain_block.hash = \
                        bi.block_id  \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_kernel where features != 'Coinbase' group by block_id) as bk  \
                     ON blockchain_block.hash = \
                        bk.block_id \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_output where output_type != 'Coinbase' group by block_id) as bo \
                     ON blockchain_block.hash = \
                        bo.block_id WHERE " +
          timeIntervalQry +
          " \
       GROUP  BY blockchain_block.hash \
       ORDER  BY blockchain_block.timestamp DESC) as x \
                group by to_char(x.timestamp,'YYYY-MM-DD') \
                order by hour_of_day asc) as t1 on to_timestamp(t1.hour_of_day, 'YYYY-MM-DD') = hours.hour",
        )
        .catch(err_msg => {
          next(err_msg);
        });
      let date = [],
        totalinput = [],
        totalkernal = [],
        totaloutput = [];

      TransactionHeatmapChartQuery.forEach(e => {
        if(moment(e.hour).format('YYYY-MM-DD') >= moment('2019-09-03').format('YYYY-MM-DD'))
        {
          date.push(moment(e.hour).format('YYYY-MM-DD'));
          totalinput.push(e.totalinput != null ? e.totalinput : 0);
          totalkernal.push(e.totalkernal != null ? e.totalkernal : 0);
          totaloutput.push(e.totaloutput != null ? e.totaloutput : 0);
        }
      });

      response.status(200).json({
        status: 200,
        timestamp: Date.now(),
        message: 'Transaction chart fetched successfully',
        response: {
          date,
          totalinput,
          totalkernal,
          totaloutput,
        },
      });
    } catch (error) {
      next(new InternalServerErrorException(error));
    }
  };
}