package dashboard

import (
	"context"
	"fmt"
	"github.com/suyuan32/simple-admin-common/msg/errormsg"
	"math"
	"strconv"
	"strings"
	"time"
	"wechat-api/ent"
	"wechat-api/ent/predicate"
	"wechat-api/ent/usagestatisticday"
	"wechat-api/ent/usagestatistichour"
	"wechat-api/ent/wx"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetWxsLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetWxsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWxsLogic {
	return &GetWxsLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx}
}

func (l *GetWxsLogic) GetWxs(req *types.WxReq) (resp *types.WxResp, err error) {
	// 获取组织id
	var organizationId uint64 = 0
	isAdmin := l.ctx.Value("isAdmin").(bool)
	if isAdmin {
		if req.OrganizationId != nil && *req.OrganizationId != 0 {
			organizationId = *req.OrganizationId
		}
	} else {
		organizationId = l.ctx.Value("organizationId").(uint64)
	}

	// 解析起始和截止时间
	layouts := []string{
		"2006-01",    // 对应 "2024-01"
		"2006-01-02", // 对应 "2024-01-01"
	}

	var layoutsType int

	var endTime time.Time
	for i, layout := range layouts {
		endTime, err = time.Parse(layout, *req.EndDate)
		layoutsType = i
		if err == nil {
			break
		}
	}
	if err != nil {
		fmt.Println("解析结束时间失败:", err)
		return
	}

	// 判断截止日期是否包含当前日
	var isCurrentDay bool
	now := time.Now()

	if layoutsType == 0 {
		isCurrentDay = endTime.Year() == now.Year() && endTime.Month() == now.Month()
	} else {
		isCurrentDay = endTime.Year() == now.Year() && endTime.Month() == now.Month() && endTime.Day() == now.Day()
	}
	var predicates []predicate.Wx
	if organizationId != 0 {
		predicates = append(predicates, wx.OrganizationID(organizationId))
	}
	if req.Wxid != nil {
		predicates = append(predicates, wx.Wxid(*req.Wxid))
	}
	wxs, err := l.svcCtx.DB.Wx.Query().Where(predicates...).All(l.ctx)

	if err != nil {
		return nil, nil
	}

	resp = &types.WxResp{}
	resp.Msg = errormsg.Success

	var wxIds []string
	wxSet := make(map[string]*ent.Wx)
	for _, w := range wxs {
		if !strings.HasPrefix(w.Wxid, "temp-") {
			wxIds = append(wxIds, w.Wxid)
			wxSet[w.Wxid] = w
		}
	}

	var wxList []types.WxData
	if isCurrentDay {
		// 返回当日每小时的数据
		var predicatesH []predicate.UsageStatisticHour
		if organizationId != 0 {
			predicatesH = append(predicatesH, usagestatistichour.OrganizationID(organizationId))
			predicatesH = append(predicatesH, usagestatistichour.BotIDIn(wxIds...))
		}
		lastHourData, err := l.svcCtx.DB.UsageStatisticHour.Query().
			Where(predicatesH...).
			Order(ent.Desc(usagestatistichour.FieldAddtime)).
			First(l.ctx)
		if err != nil {
			return nil, nil
		}
		if lastHourData == nil {
			return nil, err
		}

		var predicatesHour []predicate.UsageStatisticHour
		if organizationId != 0 {
			predicatesHour = append(predicatesHour, usagestatistichour.OrganizationID(organizationId))
		}
		predicatesHour = append(predicatesHour, usagestatistichour.BotIDIn(wxIds...))
		predicatesHour = append(predicatesHour, usagestatistichour.Addtime(lastHourData.Addtime))
		usageStatisticHour, err := l.svcCtx.DB.UsageStatisticHour.Query().Where(predicatesHour...).Page(l.ctx, req.Page, req.PageSize)
		if err != nil {
			return nil, nil
		}
		if usageStatisticHour != nil && usageStatisticHour.List != nil {
			resp.Data.Total = usageStatisticHour.PageDetails.Total
			for _, hourData := range usageStatisticHour.List {
				if wxSet[hourData.BotID] != nil {
					rate := float32(0)
					if hourData.TotalFriend != 0 {
						rate = float32(float64(hourData.ActiveUser)) / float32(float64(hourData.TotalFriend))
						rate = float32(math.Round(float64(rate) * 100))
					}
					wxList = append(wxList, types.WxData{
						Nickname:        wxSet[hourData.BotID].Nickname,
						InteractionRate: rate,
						TotalFriend:     hourData.TotalFriend,
						TotalGroup:      hourData.TotalGroup,
					})
				}
			}
		}
	} else {
		endAddTimeString := endTime.Format("20060102")
		endAddTime, err := strconv.ParseUint(endAddTimeString, 10, 64)
		if err != nil {
			fmt.Println("转换截止时间失败:", err)
			return nil, err
		}
		var predicatesDay []predicate.UsageStatisticDay
		if organizationId != 0 {
			predicatesDay = append(predicatesDay, usagestatisticday.OrganizationID(organizationId))
		}
		predicatesDay = append(predicatesDay, usagestatisticday.BotIDIn(wxIds...))
		predicatesDay = append(predicatesDay, usagestatisticday.Addtime(endAddTime))
		usageStatisticDay, err := l.svcCtx.DB.UsageStatisticDay.Query().
			Where(predicatesDay...).Page(l.ctx, req.Page, req.PageSize)
		if err != nil {
			return nil, err
		}
		if usageStatisticDay != nil && usageStatisticDay.List != nil {
			resp.Data.Total = usageStatisticDay.PageDetails.Total
			for _, dayData := range usageStatisticDay.List {
				if wxSet[dayData.BotID] != nil {
					rate := float32(0)
					if dayData.TotalFriend != 0 {
						rate = float32(float64(dayData.ActiveUser)) / float32(float64(dayData.TotalFriend))
						rate = float32(math.Round(float64(rate) * 100))
					}
					wxList = append(wxList, types.WxData{
						Nickname:        wxSet[dayData.BotID].Nickname,
						InteractionRate: rate,
						TotalFriend:     dayData.TotalFriend,
						TotalGroup:      dayData.TotalGroup,
					})
				}
			}
		}
	}

	resp.Data.Data = wxList

	return resp, nil
}
