package label_relationship

import (
	"context"
	"time"
	"wechat-api/ent"
	"wechat-api/ent/contact"
	"wechat-api/ent/label"
	"wechat-api/ent/labelrelationship"
	"wechat-api/ent/wx"

	"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 GetLabelRelationshipListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

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

func (l *GetLabelRelationshipListLogic) GetLabelRelationshipList(req *types.LabelRelationshipListReq) (*types.LabelRelationshipListResp, error) {
	organizationId := l.ctx.Value("organizationId").(uint64)
	var labPreds []predicate.Label
	labPreds = append(labPreds, label.OrganizationIDEQ(organizationId))

	var predicates []predicate.LabelRelationship
	layout := "2006-01-02 15:04:05"
	var startTime, endTime *time.Time

	if req.SearchDate != nil && len(req.SearchDate) == 2 {
		startStr := *req.SearchDate[0] + " 00:00:00"
		if t, err := time.Parse(layout, startStr); err == nil {
			//t = t.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
			startTime = &t
		} else {
			l.Logger.Errorf("invalid startDate: %v", err)
		}
		endStr := *req.SearchDate[1] + " 23:59:59"
		if t, err := time.Parse(layout, endStr); err == nil {
			//t = t.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
			endTime = &t
		} else {
			l.Logger.Errorf("invalid endDate: %v", err)
		}
	}

	if startTime != nil {
		predicates = append(predicates, labelrelationship.CreatedAtGTE(*startTime))
	}
	if endTime != nil {
		predicates = append(predicates, labelrelationship.CreatedAtLTE(*endTime))
	}

	if len(req.LabelIDs) > 0 {
		predicates = append(predicates,
			labelrelationship.HasLabelsWith(label.IDIn(req.LabelIDs...)),
		)
	}

	var conPreds []predicate.Contact
	if req.Ctype != nil {
		conPreds = append(conPreds, contact.Ctype(*req.Ctype))
	} else {
		conPreds = append(conPreds, contact.Ctype(1)) // 默认 Ctype = 1
	}

	if req.WxWxid != nil {
		conPreds = append(conPreds, contact.WxWxidContains(*req.WxWxid))
	}
	if req.Wxid != nil {
		conPreds = append(conPreds, contact.WxidContains(*req.Wxid))
	}

	if req.Type != nil {
		conPreds = append(conPreds, contact.TypeEQ(*req.Type))
	} else {
		conPreds = append(conPreds, contact.Or(contact.TypeEQ(1), contact.TypeEQ(2)))
	}

	if req.Nickname != nil {
		conPreds = append(conPreds, contact.NicknameContains(*req.Nickname))
	}

	predicates = append(predicates, labelrelationship.HasLabelsWith(labPreds...))
	if len(conPreds) > 0 {
		predicates = append(predicates, labelrelationship.HasContactsWith(conPreds...))
	}

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

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

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

	wxWxids := []string{}
	wxWxidsSet := make(map[string]*ent.Wx)
	logx.Info("data.List", data.List)
	for _, v := range data.List {
		logx.Info("v.Edges.Contacts", v.Edges.Contacts)
		if v.Edges.Contacts != nil {
			wxWxids = append(wxWxids, v.Edges.Contacts.WxWxid)
		}
	}
	logx.Info("wxWxids", wxWxids)
	wxs, err := l.svcCtx.DB.Wx.Query().Where(wx.WxidIn(wxWxids...)).All(l.ctx)
	for _, w := range wxs {
		wxWxidsSet[w.Wxid] = w
	}

	for _, v := range data.List {
		c := v.Edges.Contacts
		label := v.Edges.Labels
		wwx := wxWxidsSet[c.WxWxid]
		logx.Info("c", c)
		logx.Info("label", label)
		logx.Info("wwx", wwx)
		if c == nil || label == nil || wwx == nil {
			continue
		}
		labelRelationships := make([]types.ContactLabelList, 0)
		labelRelationships = append(labelRelationships, types.ContactLabelList{
			Label: &label.Name,
			Value: &label.ID,
		})
		resp.Data.Data = append(resp.Data.Data,
			types.ContactInfo{
				BaseIDInfo: types.BaseIDInfo{
					Id:        &v.ID,
					CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
					UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
				},
				Status:             &v.Status,
				WxWxid:             &c.WxWxid,
				WxWxidNickname:     &wwx.Nickname,
				Type:               &c.Type,
				Wxid:               &c.Wxid,
				Account:            &c.Account,
				Nickname:           &c.Nickname,
				Markname:           &c.Markname,
				Headimg:            &c.Headimg,
				Sex:                &c.Sex,
				Starrole:           &c.Starrole,
				Dontseeit:          &c.Dontseeit,
				Dontseeme:          &c.Dontseeme,
				Lag:                &c.Lag,
				Gid:                &c.Gid,
				Gname:              &c.Gname,
				V3:                 &c.V3,
				Ctype:              &c.Ctype,
				Cname:              &c.Cname,
				Cage:               &c.Cage,
				Carea:              &c.Carea,
				Cc:                 &c.Cc,
				Phone:              &c.Phone,
				Cbirthday:          &c.Cbirthday,
				Cbirtharea:         &c.Cbirtharea,
				CidcardNo:          &c.CidcardNo,
				Ctitle:             &c.Ctitle,
				LabelRelationships: labelRelationships,
			})
	}

	return resp, nil
}
