package credit_usage

import (
	"context"
	"github.com/suyuan32/simple-admin-core/rpc/types/core"
	"time"

	"wechat-api/ent/creditusage"
	"wechat-api/ent/predicate"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"
	"wechat-api/internal/utils/dberrorhandler"

	"github.com/suyuan32/simple-admin-common/msg/errormsg"

	"github.com/suyuan32/simple-admin-common/utils/pointy"
	"github.com/zeromicro/go-zero/core/logx"
)

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

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

func (l *GetCreditUsageListLogic) GetCreditUsageList(req *types.CreditUsageListReq) (*types.CreditUsageListResp, error) {
	isAdmin := l.ctx.Value("isAdmin").(bool)
	var predicates []predicate.CreditUsage
	if isAdmin {
		if req.OrganizationId != nil && *req.OrganizationId > 0 {
			predicates = append(predicates, creditusage.OrganizationID(*req.OrganizationId))
		}
	} else {
		organizationId := l.ctx.Value("organizationId").(uint64)
		predicates = append(predicates, creditusage.OrganizationID(organizationId))
	}

	if req.Ntype != nil && *req.Ntype > 0 {
		predicates = append(predicates, creditusage.Ntype(*req.Ntype))
	}

	// 这里是为限制时间段
	if req.SearchDate != nil && len(req.SearchDate) == 2 {
		startDate, err := time.Parse("2006-01-02 15:04:05", req.SearchDate[0])
		if err != nil {
			l.Logger.Errorf("时间字符串startDate转换错误: %v", err)
		} else {
			predicates = append(predicates, creditusage.CreatedAtGTE(startDate))
		}

		endDate, err := time.Parse("2006-01-02 15:04:05", req.SearchDate[1])
		if err != nil {
			l.Logger.Errorf("时间字符串endDate转换错误: %v", err)
		} else {
			predicates = append(predicates, creditusage.CreatedAtLTE(endDate))
		}
	}

	data, err := l.svcCtx.DB.CreditUsage.Query().Where(predicates...).Page(l.ctx, req.Page, req.PageSize)

	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
	}

	resp := &types.CreditUsageListResp{}
	resp.Msg = errormsg.Success
	resp.Data.Total = data.PageDetails.Total

	orgaMap := make(map[uint64]string)
	operMap := make(map[string]string)

	for _, v := range data.List {
		organizationName := ""
		if oname, ok := orgaMap[v.OrganizationID]; ok {
			organizationName = oname
		} else {
			departmentInfo, err := l.svcCtx.CoreRpc.GetDepartmentById(l.ctx, &core.IDReq{Id: v.OrganizationID})
			if err == nil {
				organizationName = *departmentInfo.Name
				orgaMap[v.OrganizationID] = organizationName
			}
		}

		operatorName := ""
		if v.Operator != "" {
			if uname, ok := operMap[v.Operator]; ok {
				operatorName = uname
			} else {
				userInfo, err := l.svcCtx.CoreRpc.GetUserById(l.ctx, &core.UUIDReq{Id: v.Operator})
				if err == nil {
					operatorName = *userInfo.Nickname
					if operatorName == "" {
						operatorName = *userInfo.Username
					}
					operMap[v.Operator] = operatorName
				}
			}
		}

		resp.Data.Data = append(resp.Data.Data,
			types.CreditUsageInfo{
				BaseIDInfo: types.BaseIDInfo{
					Id:        &v.ID,
					CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
					UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
				},
				Number:           &v.Number,
				BeforeNumber:     &v.BeforeNumber,
				AfterNumber:      &v.AfterNumber,
				PayNumber:        &v.PayNumber,
				PayMethod:        &v.PayMethod,
				Status:           &v.Status,
				Ntype:            &v.Ntype,
				Table:            &v.Table,
				OrganizationId:   &v.OrganizationID,
				OrganizationName: &organizationName,
				Nid:              &v.Nid,
				Reason:           &v.Reason,
				Operator:         &v.Operator,
				OperatorName:     &operatorName,
			})
	}

	return resp, nil
}
