package activity

import (
	"context"

	"bindbox-game/internal/repository/mysql/dao"
	"bindbox-game/internal/repository/mysql/model"
)

// CopyActivity 复制活动及其期次与奖励
// 参数: activityID 源活动ID
// 返回: 新活动ID与错误
func (s *service) CopyActivity(ctx context.Context, activityID int64) (int64, error) {
	var newActivityID int64
	err := s.writeDB.Transaction(func(tx *dao.Query) error {
		src, err := s.readDB.Activities.WithContext(ctx).Where(s.readDB.Activities.ID.Eq(activityID)).First()
		if err != nil {
			return err
		}

		newAct := &model.Activities{
			Name:               src.Name,
			Banner:             src.Banner,
			ActivityCategoryID: src.ActivityCategoryID,
			Status:             1,
			PriceDraw:          src.PriceDraw,
			IsBoss:             src.IsBoss,
		}
		if err := tx.Activities.WithContext(ctx).Omit(
			tx.Activities.StartTime,
			tx.Activities.EndTime,
			tx.Activities.ScheduledTime,
			tx.Activities.LastSettledAt,
		).Create(newAct); err != nil {
			return err
		}
		newActivityID = newAct.ID

		issues, err := s.readDB.ActivityIssues.WithContext(ctx).Where(s.readDB.ActivityIssues.ActivityID.Eq(activityID)).Order(s.readDB.ActivityIssues.Sort.Desc()).Find()
		if err != nil {
			return err
		}

		idMap := make(map[int64]int64, len(issues))
		for _, srcIssue := range issues {
			ni := &model.ActivityIssues{
				ActivityID:  newActivityID,
				IssueNumber: srcIssue.IssueNumber,
				Status:      3,
				Sort:        srcIssue.Sort,
			}
			if err := tx.ActivityIssues.WithContext(ctx).Create(ni); err != nil {
				return err
			}
			idMap[srcIssue.ID] = ni.ID
		}

		if len(idMap) == 0 {
			return nil
		}

		oldIDs := make([]int64, 0, len(idMap))
		for k := range idMap {
			oldIDs = append(oldIDs, k)
		}

		rewards, err := s.readDB.ActivityRewardSettings.WithContext(ctx).Where(s.readDB.ActivityRewardSettings.IssueID.In(oldIDs...)).Order(s.readDB.ActivityRewardSettings.Sort.Desc()).Find()
		if err != nil {
			return err
		}

		for _, r := range rewards {
			nr := &model.ActivityRewardSettings{
				IssueID:     idMap[r.IssueID],
				ProductID:   r.ProductID,
				Weight:      r.Weight,
				Quantity:    r.Quantity,
				OriginalQty: r.OriginalQty,
				Level:       r.Level,
				Sort:        r.Sort,
				IsBoss:      r.IsBoss,
			}
			if err := tx.ActivityRewardSettings.WithContext(ctx).Create(nr); err != nil {
				return err
			}
		}

		return nil
	})
	if err != nil {
		return 0, err
	}
	return newActivityID, nil
}
