import { Types } from 'mongoose'

export class dashboard_aggregation {

  static match_data_with_workspace_id = async (workspace_id: string) => {
    try {
      return {
        $match: {
          workspace_id: new Types.ObjectId(workspace_id),
        }
      }
    } catch (error) {
      throw error
    }
  }

    static match_data_with_type = async (type: string) => {
        try {
            return {
                $match: {
                    type: type
                }
            }
        } catch (error) {
            throw error
        }
    }

    static agent_lookup = async() => {
        try {
            return {
                $lookup: {
                    from: "agents",
                    let: { user_id: "$_id" },
                    pipeline: [
                        {
                            $match: {
                                $expr: {
                                    $and: [
                                        { $eq: ["$_id", "$$user_id"] },
                                    ]
                                }
                            }
                        },
                        {
                            $project: {
                                name: 1,
                                image: 1
                            }
                        }
                    ],
                    as: "agent"
                }
            }
        } catch (error) {
            throw error
        }
    }

    static agent_unwind = async() => {
        try {
            return {
                $unwind: {
                    path: "$agent",
                    preserveNullAndEmptyArrays: true,
                }
            }
        } catch (error) {
            throw error
        }
    }

    static parse_call_duration = async() => {
        try {
            return {
                $addFields: {
                    durationNum: { $toDouble: "$call_duration" }
                }
            }
        } catch (error) {
            throw error
        }
    }

    static parse_chat_duration = async() => {
        try {
            return {
                $addFields: {
                    durationNum: { $toDouble: "$chat_duration" }
                }
            }
        } catch (error) {
            throw error
        }
    }

    static group_call_by_agents = async() => {
        try {
            return {
                $group: {
                  _id: "$agent_id",
                  call_count: { $sum: 1 },
                  count: { $sum: 1 },
                  total_duration: { $sum: "$durationNum" }, 
                  avg_duration: { $avg: "$durationNum" }, 
                  emotions: { $push: "$emotion" }
                }
              }
        } catch (error) {
            throw error
        }
    }

    static sentiment_breakdown = async() => {
        try {
            return {
                $addFields: {
                  sentiment_breakdown: {
                    $reduce: {
                      input: "$emotions",
                      initialValue: { Positive: 0, Neutral: 0, Negative: 0 },
                      in: {
                        Positive: {
                          $add: [
                            "$$value.Positive",
                            {
                              $cond: {
                                if: { $in: ["$$this", ["Customer Satisfied\n", "Customer Interested\n"]] },
                                then: 1,
                                else: 0
                              }
                            }
                          ]
                        },
                        Neutral: {
                          $add: [
                            "$$value.Neutral",
                            {
                              $cond: {
                                if: { $in: ["$$this", ["Customer Indifferent\n", "Customer uninterested\n"]] },
                                then: 1,
                                else: 0
                              }
                            }
                          ]
                        },
                        Negative: {
                          $add: [
                            "$$value.Negative",
                            {
                              $cond: {
                                if: { $in: ["$$this", ["Customer Frustrated\n", "Customer Angry\n"]] },
                                then: 1,
                                else: 0
                              }
                            }
                          ]
                        }
                      }
                    }
                  },
                  total_emotions: {
                    $size: "$emotions"
                  }
                }
            }
        } catch (error) {
            throw error
        }
    }

    static sentiment_percentage_and_top_emotion = async() => {
        try {
            return {
                $addFields: {
                  sentiment_percentage: {
                    Positive: {
                        $round: [
                          {
                            $multiply: [
                              { $divide: ["$sentiment_breakdown.Positive", "$total_emotions"] },
                              100
                            ]
                          },
                          2
                        ]
                      },
                      Neutral: {
                        $round: [
                          {
                            $multiply: [
                              { $divide: ["$sentiment_breakdown.Neutral", "$total_emotions"] },
                              100
                            ]
                          },
                          2
                        ]
                      },
                      Negative: {
                        $round: [
                          {
                            $multiply: [
                              { $divide: ["$sentiment_breakdown.Negative", "$total_emotions"] },
                              100
                            ]
                          },
                          2
                        ]
                    }
                  },
                  topEmotion: {
                    $switch: {
                      branches: [
                        {
                          case: {
                            $gte: [
                              "$sentiment_breakdown.Positive",
                              { $max: ["$sentiment_breakdown.Neutral", "$sentiment_breakdown.Negative"] }
                            ]
                          },
                          then: "Positive"
                        },
                        {
                          case: {
                            $gte: [
                              "$sentiment_breakdown.Neutral",
                              { $max: ["$sentiment_breakdown.Positive", "$sentiment_breakdown.Negative"] }
                            ]
                          },
                          then: "Neutral"
                        },
                        {
                          case: {
                            $gte: [
                              "$sentiment_breakdown.Negative",
                              { $max: ["$sentiment_breakdown.Positive", "$sentiment_breakdown.Neutral"] }
                            ]
                          },
                          then: "Negative"
                        }
                      ],
                      default: null
                    }
                  }
                }
            }
        } catch (error) {
            throw error
        }
    }

    // currently not in use
    static duration_formatted = async() => {
        try {
            return {
                $addFields: {
                  total_duration_formatted: {
                    $let: {
                      vars: {
                        hours: { $floor: { $divide: ["$total_duration", 3600000] } },
                        minutes: { $floor: { $divide: [{ $mod: ["$total_duration", 3600000] }, 60000] } },
                        seconds: { $floor: { $divide: [{ $mod: ["$total_duration", 60000] }, 1000] } } 
                      },
                      in: {
                        $concat: [
                          { $toString: "$$hours" }, "h ",
                          { $toString: "$$minutes" }, "m ",
                          { $toString: "$$seconds" }, "s"
                        ]
                      }
                    }
                  },
                  avg_duration_formatted: {
                    $let: {
                      vars: {
                        hours: { $floor: { $divide: ["$avg_duration", 3600000] } }, 
                        minutes: { $floor: { $divide: [{ $mod: ["$avg_duration", 3600000] }, 60000] } },
                        seconds: { $floor: { $divide: [{ $mod: ["$avg_duration", 60000] }, 1000] } } 
                      },
                      in: {
                        $concat: [
                          { $toString: "$$hours" }, "h ",
                          { $toString: "$$minutes" }, "m ",
                          { $toString: "$$seconds" }, "s"
                        ]
                      }
                    }
                  }
                }
            }
        } catch (error) {
            throw error
        }
    }

    static call_duration_from_miliseconds = async() => {
        try {
            return {
                $addFields: {
                    total_duration_formatted: {
                        hours: { $floor: { $divide: ["$total_duration", 3600000] } }, 
                        minutes: { $floor: { $divide: [{ $mod: ["$total_duration", 3600000] }, 60000] } }, 
                        seconds: { $floor: { $divide: [{ $mod: ["$total_duration", 60000] }, 1000] } } 
                    },
                      avg_duration_formatted: {
                        hours: { $floor: { $divide: ["$avg_duration", 3600000] } },
                        minutes: { $floor: { $divide: [{ $mod: ["$avg_duration", 3600000] }, 60000] } }, 
                        seconds: { $floor: { $divide: [{ $mod: ["$avg_duration", 60000] }, 1000] } } 
                    }
                }
            }              
        } catch (error) {
            throw error
        }
    }

    static call_duration_from_seconds = async() => {
        try {
            return {
                $addFields: {
                    total_duration_formatted: {
                        hours: { $floor: { $divide: ["$total_duration", 3600] } }, 
                        minutes: { $floor: { $divide: [{ $mod: ["$total_duration", 3600] }, 60] } }, 
                        seconds: { $round: [{ $mod: ["$total_duration", 60] }, 2] } 
                    },
                      avg_duration_formatted: {
                        hours: { $floor: { $divide: ["$avg_duration", 3600] } },
                        minutes: { $floor: { $divide: [{ $mod: ["$avg_duration", 3600] }, 60] } }, 
                        seconds: { $round: [{ $mod: ["$avg_duration", 60] }, 2] } 
                    }
                }
            }              
        } catch (error) {
            throw error
        }
    }

    static project_agent_list_call = async() => {
        try {
            return {
                $project: {
                  _id: 1,
                  call_count: 1,
                  count: 1,
                  total_duration: 1,
                  avg_duration: 1,
                  total_duration_formatted: 1,
                  avg_duration_formatted: 1,
                  top_emotion: 1,
                //   sentiment_breakdown: 1,
                  sentiment_percentage: 1,
                  name: "$agent.name",
                  image: "$agent.image"
                }
            }
        } catch (error) {
            throw error
        }
    }

    static facetData = async (page: any, limit: any) => {
        try {
            page = page != undefined ? page : 0;
            limit = limit != undefined ? limit : 10;
            return {
                $facet: {
                    count: [{ $count: "count" }],
                    data: [
                        { $sort: { _id: -1 } as { _id: -1 } },
                        { $skip: parseInt(page) * parseInt(limit) },
                        { $limit: parseInt(limit) },
                    ],
                },
            };
        } catch (err) {
            throw err;
        }
    }
}