//relatorio

import { Request, Response } from "express";
import AppError from "../errors/AppError";
import ShowTicketReport from "../services/TicketServices/ShowTicketReport";
import ShowMessageReport from "../services/MessageServices/ShowMessageReport";
import onlineUserService from "../services/UserServices/CreateOrUpdateOnlineUserService";
import User from "../models/User";
import Queue from "../models/Queue";
import UserOnlineTime from "../models/UserOnlineTime";
import { Op, Sequelize, literal } from "sequelize";
import format from "date-fns/format";
import ptBR from "date-fns/locale/pt-BR";
import { splitDateTime } from "../helpers/SplitDateTime";
import ListUserOnlineOffline from "../services/UserServices/ListUsersOnlineOfflineService";
import ListUserParamiterService from "../services/UserServices/ListUserParamiterService";
import ShowUserServiceReport from "../services/UserServices/ShowUserServiceReport";
import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue";
import ShowQueuesByUser from "../services/UserServices/ShowQueuesByUser";
import { getIO } from "../libs/socket";
import { Json } from "sequelize/types/lib/utils";
import ReportByNumberQueueService from "../services/ReportServices/ReportByNumberQueueService";
import CountStatusChatEndService from "../services/StatusChatEndService/CountStatusChatEndService";

type IndexQuery = {
  userId: string;
  startDate: string;
  endDate: string;
  createdOrUpdated: string;
  queueId: string;
  pageNumber: string;
  userQueues: [];
  isRemote: string;
};

type ReportOnQueue = {
  userId: string;
  identifier: string;
};

export const reportUserByDateStartDateEnd = async (
  req: Request,
  res: Response
): Promise<Response> => {
  if (
    req.user.profile !== "master" &&
    req.user.profile !== "admin" &&
    req.user.profile !== "supervisor"
  ) {
    throw new AppError("ERR_NO_PERMISSION", 403);
  }

  const {
    userId,
    startDate,
    endDate,
    pageNumber,
    userQueues,
    createdOrUpdated,
    queueId
  } = req.query as IndexQuery;

  const { tickets, count, hasMore } = await ShowTicketReport({
    userId,
    startDate,
    endDate,
    pageNumber,
    createdOrUpdated,
    queueId,
  });

  const queues = await Queue.findAll({ attributes: ["id", "name"] });

  return res.status(200).json({ tickets, count, hasMore, queues });
};

export const reportUserService = async (
  req: Request,
  res: Response
): Promise<Response> => {
  if (
    req.user.profile !== "master" &&
    req.user.profile !== "admin" &&
    req.user.profile !== "supervisor"
  ) {
    throw new AppError("ERR_NO_PERMISSION", 403);
  }
  const { userId, startDate, endDate, userQueues} = req.query as IndexQuery;

  // let usersProfile = await ListUserParamiterService({ profile: 'user' })
  let usersProfile = await ListUserParamiterService({
    profiles: ["user", "supervisor"],
    userQueues: userQueues ? userQueues : undefined,
    raw: true
  });

  const sumUserOlineTime = await ShowUserServiceReport({
    startDate,
    endDate,
    userId
  });
  const closedByUser = await ShowUserServiceReport({
    startDate,
    endDate,
    ticketStatus: "closed",
    userId
  });
  const openByUser = await ShowUserServiceReport({
    startDate,
    endDate,
    ticketStatus: "open",
    userId
  });

  let dateTime = splitDateTime(
    new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
  );
  const onlineUsers = await ListUserOnlineOffline({ date: dateTime.fullDate });

  const openByUserOnQueue = await CountTicketsByUserQueue({
    startDate: startDate,
    endDate: endDate,
    status: "open",
    clientChatStart: true
  });
  const openByUserOutQueue = await CountTicketsByUserQueue({
    startDate: startDate,
    endDate: endDate,
    status: "open",
    clientChatStart: false
  });

  const closedByUserOnQueue = await CountTicketsByUserQueue({
    startDate: startDate,
    endDate: endDate,
    status: "closed",
    clientChatStart: true
  });
  const closedUserOutQueue = await CountTicketsByUserQueue({
    startDate: startDate,
    endDate: endDate,
    status: "closed",
    clientChatStart: false
  });

  // let openQueueInOut = openByUserOnQueue.concat(openByUserOutQueue)
  // let closedQueueInOut = closedByUserOnQueue.concat(closedUserOutQueue)

  const queuesByUser = await ShowQueuesByUser({ profile: "user" });

  let openCloseOnQueue = openByUserOnQueue.concat(closedByUserOnQueue);
  let openCloseOutQueue = openByUserOutQueue.concat(closedUserOutQueue);

  // console.log('onlineUsers: ',JSON.parse(JSON.stringify(onlineUsers)))
  // console.log('sumUserOlineTime: ', JSON.parse(JSON.stringify(sumUserOlineTime)))

  for (let i = 0; i < queuesByUser.length; i++) {
    queuesByUser[i].countOpen = 0;
    queuesByUser[i].countClosed = 0;

    for (let x = 0; x < openCloseOnQueue.length; x++) {
      if (
        queuesByUser[i].userId == openCloseOnQueue[x].userId &&
        queuesByUser[i].queueId == openCloseOnQueue[x].queueId &&
        openCloseOnQueue[x].status == "open"
      ) {
        queuesByUser[i].countOpen = openCloseOnQueue[x].totAttendance;
      } else if (
        queuesByUser[i].userId == openCloseOnQueue[x].userId &&
        queuesByUser[i].queueId == openCloseOnQueue[x].queueId &&
        openCloseOnQueue[x].status == "closed"
      ) {
        queuesByUser[i].countClosed = openCloseOnQueue[x].totAttendance;
      }
    }
  }

  usersProfile.map((user: any) => {
    let index = sumUserOlineTime.findIndex((e: any) => e.userId == user.id);

    if (index != -1) {
      user.sumOnlineTime = sumUserOlineTime[index];

      // console.log('user.sumOlineTime: 'user.sumOnlineTime)
    }

    index = closedByUser.findIndex((e: any) => e.userId == user.id);

    if (index != -1) {
      user.sumClosed = closedByUser[index];
    }

    index = openByUser.findIndex((e: any) => e.userId == user.id);

    if (index != -1) {
      user.sumOpen = openByUser[index];
    }

    // OPEN, CLOSED TICKETS STARTED BY USERS
    let openClosedOutQueue = {};
    let open = openCloseOutQueue.filter(
      e => e.userId == user.id && e.status == "open"
    );
    let closed = openCloseOutQueue.filter(
      e => e.userId == user.id && e.status == "closed"
    );

    openClosedOutQueue = {
      ...openClosedOutQueue,
      userId: user.id,
      countOpen: open && open.length > 0 ? open[0].totAttendance : 0,
      countClosed: closed && closed.length > 0 ? closed[0].totAttendance : 0
    };

    user.openClosedOutQueue = openClosedOutQueue;

    // OPEN, CLOSED TICKETS STARTED BY CLIENTS
    let openClosedInQueue = queuesByUser.filter(e => e.userId == user.id);

    if (openClosedInQueue && openClosedInQueue.length > 0) {
      user.openClosedInQueue = openClosedInQueue;
    }

    index = onlineUsers.findIndex((e: any) => e.userId == user.id);

    if (index != -1) {
      user.statusOnline = onlineUsers[index];
    }

    if (startDate.length > 0 && startDate.split("-").length == 3) {
      let date = startDate.split("-");
      user.startDate = `${date[2]}/${date[1]}/${date[0]}`;
    }

    if (endDate.length > 0 && endDate.split("-").length == 3) {
      let date = endDate.split("-");
      user.endDate = `${date[2]}/${date[1]}/${date[0]}`;
    }
  });

  return res.status(200).json({ usersProfile: usersProfile });
};

export const reportMessagesUserByDateStartDateEnd = async (
  req: Request,
  res: Response
): Promise<Response> => {
  if (
    req.user.profile !== "master" &&
    req.user.profile !== "admin" &&
    req.user.profile !== "supervisor"
  ) {
    throw new AppError("ERR_NO_PERMISSION", 403);
  }

  const { userId, startDate, endDate } = req.query as IndexQuery;

  let data_query_messages = await ShowMessageReport(userId, startDate, endDate);

  for (var i = 0; i < data_query_messages.length; i++) {
    if (data_query_messages[i].fromMe) {
      data_query_messages[i].fromMe = "Atendente";
    } else {
      data_query_messages[i].fromMe = "Cliente";
    }

    data_query_messages[i].id = i + 1;
  }

  return res.status(200).json(data_query_messages);
};

export const reportOnQueue = async (
  req: Request,
  res: Response
): Promise<Response> => {
  // console.log(req.body)

  const { adminId, identifier, queueStatus, file } = req.body;

  const io = getIO();
  io.emit("queryOnQueueStatus", {
    action: "update",
    queryOnQueue: {
      adminId: adminId,
      identifier: identifier,
      queueStatus: queueStatus,
      file: file
    }
  });

  return res.status(200).json({ message: "ok" });
};

export const reportService = async (
  req: Request,
  res: Response
): Promise<Response> => {
  if (
    req.user.profile !== "master" &&
    req.user.profile !== "admin" &&
    req.user.profile !== "supervisor"
  ) {
    throw new AppError("ERR_NO_PERMISSION", 403);
  }

  const { startDate, endDate, queueId, isRemote } = req.query as IndexQuery;

  console.log(
    `startDate: ${startDate} | endDate: ${endDate} | queueId: ${queueId}`
  );

  console.log("IS REMOTE: ", isRemote);
  console.log("isRemote: ", isRemote && isRemote == "true" ? true : false);

  const reportService = await ReportByNumberQueueService({
    startDate,
    endDate,
    isRemote: isRemote && isRemote == "true" ? true : false
  });

  return res.status(200).json({ reportService });
};

export const reportServiceByQueue = async (
  req: Request,
  res: Response
): Promise<Response> => {
  if (
    req.user.profile !== "master" &&
    req.user.profile !== "admin" &&
    req.user.profile !== "supervisor"
  ) {
    throw new AppError("ERR_NO_PERMISSION", 403);
  }

  const { startDate, endDate, queueId, isRemote } = req.query as IndexQuery;

  const reportService = await ReportByNumberQueueService({
    startDate,
    endDate,
    queue: true,
    isRemote: isRemote && isRemote == "true" ? true : false
  });

  return res.status(200).json({ reportService });
};

export const reportTicksCountByStatusChatEnds = async (
  req: Request,
  res: Response
): Promise<Response> => {
  if (
    req.user.profile !== "master" &&
    req.user.profile !== "admin" &&
    req.user.profile !== "supervisor"
  ) {
    throw new AppError("ERR_NO_PERMISSION", 403);
  }

  const { startDate, endDate, userQueues } = req.query as IndexQuery;

  const dateToday = splitDateTime(
    new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
  );
  
  const queueIds = userQueues ?  userQueues.map(queue => parseInt(queue)) : [];

  const reportStatusChatEnd = await CountStatusChatEndService(
    startDate || dateToday.fullDate,
    endDate || dateToday.fullDate,
    queueIds
  );

  return res.status(200).json({ reportStatusChatEnd });
};
