package label_relationship

import (
	"context"
	"github.com/suyuan32/simple-admin-common/msg/errormsg"
	"wechat-api/ent"
	"wechat-api/ent/contact"
	"wechat-api/ent/custom_types"
	"wechat-api/ent/labelrelationship"
	"wechat-api/ent/messagerecords"
	"wechat-api/ent/soptask"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"
	"wechat-api/internal/utils/dberrorhandler"

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

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

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

func (l *BatchUpdateLabelRelationshipsLogic) BatchUpdateLabelRelationships(req *types.BatchLabelRelationshipsInfo) (resp *types.BaseMsgResp, err error) {
	organizationId := l.ctx.Value("organizationId").(uint64)

	// 遍历所有联系人
	for _, contactId := range req.ContactIds {
		// 开始事务
		tx, err := l.svcCtx.DB.Tx(context.Background())
		if err != nil {
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}
		// 获取联系人信息
		c, err := tx.Contact.Query().Where(contact.ID(contactId), contact.OrganizationIDEQ(organizationId)).Only(l.ctx)
		// 获取联系人当前已关联的标签
		currentLabelRelationships, err := tx.LabelRelationship.Query().Where(labelrelationship.ContactID(contactId)).All(l.ctx)
		if err != nil {
			_ = tx.Rollback()
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}

		// 提取当前标签ID
		var currentLabelIds []uint64
		for _, relationship := range currentLabelRelationships {
			currentLabelIds = append(currentLabelIds, relationship.LabelID)
		}

		// 对比新旧标签ID，找出需要新增和移除的标签
		changeLabelIds, finalLabelIds := compareLabelIdsForIncrement(req.LabelIds, currentLabelIds, req.UpdateType)
		// 如果 req.UpdateType 为空，或 req.UpdateType 的值为 “all” 时
		if req.UpdateType == -1 {
			// 删除需要移除的标签关系
			for _, id := range changeLabelIds {
				_, err := tx.LabelRelationship.
					Delete().
					Where(
						labelrelationship.ContactID(contactId),
						labelrelationship.LabelID(id),
					).
					Exec(l.ctx)
				if err != nil {
					_ = tx.Rollback()
					return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
				}
			}
		} else {
			// 创建需要新增的标签关系
			for _, id := range changeLabelIds {
				_, _ = tx.LabelRelationship.Create().
					SetLabelID(id).
					SetContactID(contactId).
					SetOrganizationID(organizationId).
					Save(l.ctx)
				//if err != nil {
				//	return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
				//}
			}
		}

		// 获取所有 status 为 3 且 bot_wxid_list 包含 c.wx_wxid 的 sop_task
		sopTasks, err := tx.SopTask.Query().Where(soptask.Status(3), soptask.OrganizationIDEQ(organizationId)).All(l.ctx)
		if err != nil {
			_ = tx.Rollback()
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}

		var filteredSopTasks []*ent.SopTask
		for _, task := range sopTasks {
			for _, botWxid := range task.BotWxidList {
				if botWxid == c.WxWxid {
					filteredSopTasks = append(filteredSopTasks, task)
					break
				}
			}
		}

		// 获取所有 filteredSopTasks 的 sop_stages
		var sopStages []*ent.SopStage
		for _, task := range filteredSopTasks {
			stages, err := task.QueryTaskStages().All(l.ctx)
			if err != nil {
				_ = tx.Rollback()
				return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
			}
			sopStages = append(sopStages, stages...)
		}

		// 所有操作成功，提交事务
		err = tx.Commit()
		if err != nil {
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}

		err = l.AddLabelRelationships(sopStages, *c, finalLabelIds, organizationId, l.ctx, l.Logger)

		if err != nil {
			_ = tx.Rollback()
			return nil, err
		}
	}

	return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
}

func (l *BatchUpdateLabelRelationshipsLogic) AddLabelRelationships(sopStages []*ent.SopStage, contact ent.Contact, currentLabelIds []uint64, organizationId uint64, ctx context.Context, logger logx.Logger) (err error) {
	for _, stage := range sopStages {
		if stage.ConditionType == 1 && isLabelIdListMatchFilter(currentLabelIds, stage.ConditionOperator, stage.ConditionList) {
			// 开始事务
			tx, err := l.svcCtx.DB.Tx(context.Background())
			if err != nil {
				return dberrorhandler.DefaultEntError(l.Logger, err, nil)
			}
			// 判断是否有 contact_wxid、source_type、source_id、sub_source_id 相同的记录
			_, err = tx.MessageRecords.Query().
				Where(
					messagerecords.ContactWxid(contact.Wxid),
					messagerecords.SourceType(3),
					messagerecords.SourceID(stage.ID),
					messagerecords.SubSourceID(0),
				).
				Only(ctx)
			if err == nil {
				continue
			}
			// 判断ActionMessage是否为空
			sourceType := 3
			if stage.ActionMessage != nil {
				for i, message := range stage.ActionMessage {
					meta := custom_types.Meta{}
					if message.Meta != nil {
						meta.Filename = message.Meta.Filename
					}
					_, err = tx.MessageRecords.Create().
						SetNotNilBotWxid(&contact.WxWxid).
						SetNotNilContactID(&contact.ID).
						SetNotNilContactType(&contact.Type).
						SetNotNilContactWxid(&contact.Wxid).
						SetNotNilContentType(&message.Type).
						SetNotNilContent(&message.Content).
						SetMeta(meta).
						SetNotNilSourceType(&sourceType).
						SetNotNilSourceID(&stage.ID).
						SetSubSourceID(uint64(i)).
						SetOrganizationID(organizationId).
						Save(ctx)

					if err != nil {
						_ = tx.Rollback()
						return dberrorhandler.DefaultEntError(l.Logger, err, nil)
					}
				}
			}
			if stage.ActionForward != nil {
				if stage.ActionForward.Wxid != "" {
					forwardWxids := splitString(stage.ActionForward.Wxid)
					for _, forwardWxid := range forwardWxids {
						for i, message := range stage.ActionForward.Action {
							meta := custom_types.Meta{}
							if message.Meta != nil {
								meta.Filename = message.Meta.Filename
							}
							_, err = tx.MessageRecords.Create().
								SetBotWxid(contact.WxWxid).
								SetContactID(0).
								SetContactType(0).
								SetContactWxid(forwardWxid).
								SetContentType(message.Type).
								SetContent(message.Content).
								SetMeta(meta).
								SetSourceType(sourceType).
								SetSourceID(stage.ID).
								SetSubSourceID(contact.ID + uint64(i)).
								SetOrganizationID(organizationId).
								Save(l.ctx)

							if err != nil {
								_ = tx.Rollback()
								return dberrorhandler.DefaultEntError(l.Logger, err, nil)
							}
						}
					}
				}
			}
			if stage.ActionLabelAdd != nil || stage.ActionLabelDel != nil {

				// 获取 addLabelIds 中不在 currentLabelIds 中的标签ID
				var newLabelIds []uint64
				var remLabelIds []uint64
				var finalLabelIds []uint64
				// 创建一个映射，用于快速查找 currentLabelIds 中的元素
				currentLabelIdSet := make(map[uint64]struct{})
				for _, id := range currentLabelIds {
					currentLabelIdSet[id] = struct{}{}
				}

				delLabelIdSet := make(map[uint64]struct{})
				for _, id := range stage.ActionLabelDel {
					delLabelIdSet[id] = struct{}{}
				}

				if stage.ActionLabelAdd != nil {
					// 遍历 addLabelIds，找出不在 currentLabelIds 中的元素
					for _, id := range stage.ActionLabelAdd {
						if _, ce := currentLabelIdSet[id]; !ce {
							if _, re := delLabelIdSet[id]; !re {
								newLabelIds = append(newLabelIds, id)
							}
						}
					}

					if len(newLabelIds) > 0 {
						// 创建需要新增的标签关系
						for _, id := range newLabelIds {
							_, err = tx.LabelRelationship.Create().
								SetLabelID(id).
								SetContactID(contact.ID).
								SetOrganizationID(organizationId).
								Save(ctx)
							if err != nil {
								_ = tx.Rollback()
								return dberrorhandler.DefaultEntError(l.Logger, err, nil)
							}
						}
						// 合并 currentLabelIds 和 newLabelIds
						currentLabelIds = append(currentLabelIds, newLabelIds...)
					}
				}

				if stage.ActionLabelDel != nil {
					// 遍历 delLabelIds，找出在 currentLabelIds 中的元素
					for _, id := range stage.ActionLabelDel {
						if _, exists := currentLabelIdSet[id]; exists {
							remLabelIds = append(newLabelIds, id)
							delete(currentLabelIdSet, id)
						}
					}

					if len(remLabelIds) > 0 {
						_, err = tx.LabelRelationship.Delete().Where(labelrelationship.IDIn(remLabelIds...), labelrelationship.ContactIDEQ(contact.ID), labelrelationship.OrganizationIDEQ(organizationId)).Exec(l.ctx)
						if err != nil {
							//_ = tx.Rollback()
							return dberrorhandler.DefaultEntError(l.Logger, err, nil)
						}
					}
				}

				// 所有操作成功，提交事务
				err = tx.Commit()
				if err != nil {
					return dberrorhandler.DefaultEntError(l.Logger, err, nil)
				}

				if len(newLabelIds) == 0 && len(remLabelIds) == 0 {
					return nil
				}

				for id := range currentLabelIdSet {
					finalLabelIds = append(finalLabelIds, id)
				}

				// 递归调用 AddLabelRelationships
				err = l.AddLabelRelationships(sopStages, contact, finalLabelIds, organizationId, ctx, logger)
				if err != nil {
					return err
				}
				return nil
			} else {
				// 所有操作成功，提交事务
				err = tx.Commit()
				if err != nil {
					return dberrorhandler.DefaultEntError(l.Logger, err, nil)
				}
			}
		}
	}
	// 所有操作成功，提交事务
	//err = tx.Commit()
	//if err != nil {
	//	return dberrorhandler.DefaultEntError(l.Logger, err, nil)
	//}
	return nil
}

// compareLabelIds compares the new label ids with the current ones and returns the ids to be added and removed
func compareLabelIdsForIncrement(newLabelIds []uint64, currentLabelIds []uint64, updateType int) (changeLabelIds []uint64, finalLabelIds []uint64) {
	currentLabelIdsSet := make(map[uint64]struct{}, len(currentLabelIds))
	for _, id := range currentLabelIds {
		currentLabelIdsSet[id] = struct{}{}
	}

	for _, id := range newLabelIds {
		if updateType == 1 {
			if _, ok := currentLabelIdsSet[id]; ok {
				delete(currentLabelIdsSet, id)
			} else {
				changeLabelIds = append(changeLabelIds, id)
				finalLabelIds = append(finalLabelIds, id)
			}
		} else {
			if _, ok := currentLabelIdsSet[id]; ok {
				delete(currentLabelIdsSet, id)
				changeLabelIds = append(changeLabelIds, id)
			}
		}
	}

	for id := range currentLabelIdsSet {
		finalLabelIds = append(finalLabelIds, id)
	}

	return
}
