package service

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"pure/initialize/api"
	"strconv"
	"strings"
	"time"

	"github.com/spf13/cast"
	"gorm.io/gorm"

	"pure/global"
	"pure/model"
	"pure/model/request"
	"pure/model/response"
	"pure/utils"
)

func GetMissionDetail(uuid string, id uint) (error, model.MissionDetail) {
	var (
		err    error
		result model.MissionDetail
	)
	err = global.MG_DB.Model(&model.Mission{}).
		Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,status,create_by,has_sample,has_video,claim_stock,claim_days,claim_demands,video_channel_ids,description,claim_num,sample_num").
		Where("id = ?", id).Preload("Goods", func(db *gorm.DB) *gorm.DB {
		return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max,stock,sales").Preload("Specs", func(db *gorm.DB) *gorm.DB {
			return db.Select("id,goods_id,specs,stock,sku_no,price,image,goods_no,code").Unscoped()
		}).Unscoped()
	}).First(&result).Error

	if err != nil {
		return err, result
	}

	if result.VideoChannelIds != "" {
		channelLabels := FormatDictLabels(model.ReleaseChannelCode, strings.Split(result.VideoChannelIds, ","))
		result.ReleaseChannels = strings.Join(channelLabels, "、")
	}
	claimExcept := GetMissionStatusExcept(result, uuid)
	result.ClaimStatusExcept = claimExcept
	trs := utils.InterTranslate(claimExcept, "zh", "en")
	if trs != "" {
		result.ClaimStatusExceptEng = trs
	}

	if result.HireType == 1 { // 1:固定佣金
		result.HireMoneyExpect = utils.FormatFloatToString(result.HireMoney)
	} else { // 2:比例抽成
		if result.Goods.PriceMin == result.Goods.PriceMax {
			result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin * (result.HireRatio / 100))
		} else {
			result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin*(result.HireRatio/100)) + "-" + utils.FormatFloatToString(result.Goods.PriceMax*(result.HireRatio/100))
		}
	}
	if result.CreateBy != "" {
		_, result.Store = GetSellerStoreInfo(result.CreateBy)
	}
	result.CollectStatus = getMissionCollectStatus(uuid, result.ID)
	//
	result.GoodsUrl = global.MG_CONFIG.Tools.CustomerUrl + `/CommodityDetails?id=` + cast.ToString(result.GoodsId)
	err = getSpecs(&result.Goods)
	return nil, result
}

func getSpecs(goods *model.TbGoodsSpecsView) (err error) {
	attributeValues := make(map[uint]*model.TbAttributeValueJson)
	for i := 0; i < len(goods.Specs); i++ {
		err = json.Unmarshal([]byte(goods.Specs[i].Specs), &goods.Specs[i].Attributes)
		if err != nil {
			return err
		}
		if i == 0 {
			var attributes []uint
			for j := 0; j < len(goods.Specs[i].Attributes); j++ {
				attributes = append(attributes, goods.Specs[i].Attributes[j].AttributeId)
			}
			orderSql := "FIELD(id"
			for _, attribute := range attributes {
				orderSql += fmt.Sprintf(",'%v'", attribute)
			}
			orderSql += ")"
			err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&goods.Attributes).Error
			if err != nil {
				return err
			}
		}
		for _, attribute := range goods.Specs[i].Attributes {
			if _, ok := attributeValues[attribute.AttributeId]; ok {
				if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
					attributeValues[attribute.AttributeId].Str += attribute.Value + ","
					attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{
						Id: attribute.ValueId, Name: attribute.Value, Image: goods.Specs[i].Image})
				}
			} else {
				attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{
					Id: attribute.ValueId, Name: attribute.Value, Image: goods.Specs[i].Image}}, Str: attribute.Value + ","}
			}
		}
	}
	for i := 0; i < len(goods.Attributes); i++ {
		if val, ok := attributeValues[goods.Attributes[i].ID]; ok {
			goods.Attributes[i].Values = val.Items
		}
	}
	return
}

func GetMissionList(uuid string, info request.SearchMission) (err error, list any, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.MG_DB.Model(&model.Mission{}).Joins("INNER JOIN tb_goods ON tb_goods.id = mission.goods_id").
		Where("mission.goods_status = 1 AND tb_goods.stock > 0")
	err = db.Count(&total).Error
	var res []model.MissionDetail
	err = db.Select("mission.id,mission.title,mission.goods_id,mission.goods_status,mission.num,mission.hire_type,mission.hire_money,mission.hire_ratio,mission.start_time,mission.end_time,mission.`status`,mission.create_by,case when mission.status = 2 then 900000000 when mission.status = 1 then 500000000+mission.id else mission.id end as sort_value").
		// 分段排序逻辑:进行中--结束时间正序,未开始--id倒序,已结束--id倒序
		Preload("Goods", func(db *gorm.DB) *gorm.DB {
			return db.Select("tb_goods.id,tb_goods.spu_no,title,title_eng,tb_goods.images,tb_goods.tags,retail_price,price_min,price_max").Unscoped()
		}).Limit(limit).Offset(offset).Order("sort_value desc").Order("end_time asc").Find(&res).Error

	if err != nil {
		return err, nil, 0
	}
	var (
		ids   []uint
		uuids []string
	)
	for i := 0; i < len(res); i++ {
		if res[i].HireType == 1 { // 1:固定佣金
			res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].HireMoney)
		} else { // 2:比例抽成
			if res[i].Goods.PriceMin == res[i].Goods.PriceMax {
				// res[i].HireMoneyExpect = fmt.Sprintf("%v", res[i].Goods.PriceMin*(res[i].HireRatio/100))
				res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin * (res[i].HireRatio / 100))
			} else {
				res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin*(res[i].HireRatio/100)) + "-" + utils.FormatFloatToString(res[i].Goods.PriceMax*(res[i].HireRatio/100))
			}
		}
		if res[i].CreateBy != "" {
			uuids = append(uuids, res[i].CreateBy)
		}
		ids = append(ids, res[i].ID)
	}
	if len(ids) != 0 {
		statusMap := getMissionCollectStatusMap(uuid, ids)
		for i := 0; i < len(res); i++ {
			if val, ok := statusMap[res[i].ID]; ok {
				res[i].CollectStatus = val
			}
		}
	}
	if len(uuids) != 0 {
		_, storeMap := getSellerStoreInfoMap(uuids)
		for i := 0; i < len(res); i++ {
			if val, ok := storeMap[res[i].CreateBy]; ok {
				res[i].Store = val
			}
		}
	}
	return err, res, total
}

func getMissionClaim(uuid, claimNo string) (err error, result model.MissionClaim) {
	err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND claim_no = ?", uuid, claimNo).First(&result).Error
	return
}

func GetMissionClaim(uuid string, id uint) (err error, res model.MissionClaimDetail) {
	err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, id).
		Select("id,mission_id,claim_no,achieve_num,`status`,created_at,updated_at,expire_at,finished,email").
		Preload("Order", func(db *gorm.DB) *gorm.DB {
			return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number,send_time").
				Preload("OrderGoods", func(db *gorm.DB) *gorm.DB {
					return db.Select("order_id,price,sku_no,title,image,specs,id")
				})
		}).
		Preload("Mission", func(db *gorm.DB) *gorm.DB {
			return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`,create_by,claim_days").
				Preload("Goods", func(db *gorm.DB) *gorm.DB {
					return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
				})
		}).Preload("Works").
		Preload("Video", func(db *gorm.DB) *gorm.DB {
			return db.Where("status in (1,2)").Order("id desc").Limit(1)
		}).First(&res).Error
	if err != nil {
		return
	}
	res.Video.CreateTime = res.Video.CreatedAt

	if res.Mission.CreateBy != "" {
		_, res.Mission.Store = GetSellerStoreInfo(res.Mission.CreateBy)
	}
	if res.Mission.HireType == 1 { // 1:固定佣金
		res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.HireMoney)
	} else { // 2:比例抽成
		res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Order.OrderGoods.Price * (res.Mission.HireRatio / 100))
	}
	if res.Mission.ID != 0 {
		res.Mission.CollectStatus = getMissionCollectStatus(uuid, res.Mission.ID)
	}
	res.StatusExcept = GetMissionClaimStatusExcept(res)

	res.SpreadUrl = global.MG_CONFIG.Tools.CustomerUrl + "/CommodityDetails?id=" + fmt.Sprintf("%v", res.Mission.Goods.ID) + "&spu_no=" + res.Mission.Goods.SpuNo + "&claim_no=" + res.ClaimNo
	return
}

func MergeMissionClaimList(uuid string, info request.SearchMissionClaim) (err error, list []model.MissionClaimDetail, total int64) {
	// 进行中与已结束分段查询,在此处合并
	db := global.MG_DB.Model(&model.MissionClaim{}).Joins("inner join mission on mission.id = mission_claim.mission_id").
		Where("mission_claim.create_by = ?", uuid)
	if info.HireType != 0 {
		db = db.Where("mission.hire_type = ?", info.HireType)
	}

	//是否
	if info.VideoUpload == 1 {
		var delIds []uint
		var claimVideos []model.MissionClaimVideo
		err = global.MG_DB.Model(&model.MissionClaimVideo{}).
			Select("id,mission_id,status,create_by,mission_claim_id").
			Where("status in (1,2) and create_by = ?", uuid).
			Find(&claimVideos).Error
		for _, c := range claimVideos {
			if c.MissionClaimId != 0 {
				delIds = append(delIds, c.MissionClaimId)
			}
		}
		info.ExcludeIds = delIds
		db.Where("mission_claim.id not in (?)", info.ExcludeIds)
	}

	err = db.Count(&total).Error
	var (
		partTotal  int64
		partOffset int
		limit      int
		offset     int
		newPage    int
		endedList  []model.MissionClaimDetail
	)
	limit = info.PageSize
	offset = info.PageSize * (info.Page - 1)
	// 查询进行中的数据
	info.MissionStatus = 2
	err, list, partTotal = GetMissionClaimList(uuid, info, offset, limit)
	if len(list) < limit {
		// 查询已结束的数据补齐
		info.MissionStatus = 3
		// 进行中总页数
		newPage = info.Page - int(math.Ceil(float64(partTotal)/float64(limit)))
		partOffset = int(partTotal) % limit
		if len(list) > 0 {
			limit = info.PageSize - len(list)
			offset = 0
		} else {
			limit = info.PageSize
			offset = info.PageSize*newPage - partOffset
		}

		err, endedList, partTotal = GetMissionClaimList(uuid, info, offset, limit)
		list = append(list, endedList...)
	}

	return err, list, total
}

func GetMissionClaimList(uuid string, info request.SearchMissionClaim, offset, limit int) (err error, list []model.MissionClaimDetail, total int64) {
	db := global.MG_DB.Model(&model.MissionClaim{}).Where("mission_claim.create_by = ?", uuid)

	var res []model.MissionClaimDetail

	db = db.Joins("inner join mission on mission.id = mission_claim.mission_id").
		Select("mission_claim.id,mission_claim.mission_id,mission_claim.claim_no,mission_claim.achieve_num,mission_claim.`status`,mission_claim.created_at,mission_claim.updated_at,mission_claim.expire_at,mission_claim.finished").Preload("Order", func(db *gorm.DB) *gorm.DB {
		return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number").
			Preload("OrderGoods", func(db *gorm.DB) *gorm.DB {
				return db.Select("order_id,sku_no,title,specs,image,price").Unscoped()
			})
	}).Preload("Mission", func(db *gorm.DB) *gorm.DB {
		return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`,create_by").
			Preload("Goods", func(db *gorm.DB) *gorm.DB {
				return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
			})
	})

	if info.HireType != 0 {
		db = db.Where("mission.hire_type = ?", info.HireType)
	}

	if len(info.ExcludeIds) != 0 {
		db.Where("mission_claim.id not in (?)", info.ExcludeIds)
	}

	if info.MissionStatus == 2 {
		db = db.Where("mission.status = 2").Order("mission_claim.expire_at asc")
	} else {
		db = db.Where("mission.status != 2")
	}

	err = db.Count(&total).Error
	err = db.Order("mission_claim.id DESC").Limit(limit).Offset(offset).Find(&res).Error

	if err != nil {
		return err, nil, 0
	}
	var (
		ids     []uint
		uuids   []string
		resList []response.MissionClaimView
	)
	for i := 0; i < len(res); i++ {
		var vMissionClaim response.MissionClaimView

		if res[i].Mission.CreateBy != "" {
			uuids = append(uuids, res[i].Mission.CreateBy)
		}
		if res[i].Mission.HireType == 1 { // 1:固定佣金
			res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.HireMoney)
		} else { // 2:比例抽成
			res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Order.OrderGoods.Price * (res[i].Mission.HireRatio / 100))
		}
		res[i].SpreadUrl = global.MG_CONFIG.Tools.CustomerUrl + "/CommodityDetails?id=" + fmt.Sprintf("%v", res[i].Mission.Goods.ID) + "&spu_no=" + res[i].Mission.Goods.SpuNo + "&claim_no=" + res[i].ClaimNo

		if res[i].Mission.ID != 0 {
			ids = append(ids, res[i].Mission.ID)
		}
		vRes := res[i]
		vMissionClaim.MissionId = vRes.MissionId
		vMissionClaim = response.MissionClaimView{
			ID:              vRes.ID,
			ClaimNo:         vRes.ClaimNo,
			MissionId:       vRes.MissionId,
			AchieveNum:      vRes.AchieveNum,
			Status:          vRes.Status,
			SpreadUrl:       vRes.SpreadUrl,
			HireType:        vRes.Mission.HireType,
			HireMoneyExpect: vRes.Mission.HireMoneyExpect,
			EndTime:         vRes.Mission.EndTime,
			ExpireAt:        vRes.ExpireAt,
			CollectStatus:   false,
			Goods: response.MissionGoodsView{
				GoodsId:  vRes.Mission.GoodsId,
				SkuNo:    vRes.Order.OrderGoods.SkuNo,
				Title:    vRes.Order.OrderGoods.Title,
				Images:   vRes.Order.OrderGoods.Image,
				Price:    vRes.Order.OrderGoods.Price,
				SpuNo:    vRes.Mission.Goods.SpuNo,
				TitleEng: vRes.Mission.Goods.TitleEng,
			},
		}

		resList = append(resList, vMissionClaim)
	}
	if len(ids) != 0 {
		statusMap := getMissionCollectStatusMap(uuid, ids)
		for i := 0; i < len(res); i++ {
			res[i].Mission.CollectStatus = statusMap[res[i].ID]
		}
	}
	if len(uuids) != 0 {
		_, storeMap := getSellerStoreInfoMap(uuids)
		for i := 0; i < len(res); i++ {
			if val, ok := storeMap[res[i].Mission.CreateBy]; ok {
				res[i].Mission.Store = val
			}
		}
	}

	return err, res, total
}

func ClaimMission(uuid string, info request.ClaimMission) (err error, id uint) {
	var mission model.Mission
	//查询网红是否被禁用
	var user model.User
	err = global.MG_DB.Model(&model.User{}).Where("uuid = ?", uuid).First(&user).Error
	if err != nil {
		return errors.New("未找到用户信息"), 0
	}
	if user.IDForbidden {
		return errors.New("账号已被禁用"), 0
	}
	if global.MG_DB.Model(&model.Mission{}).Where("id = ?", info.MissionId).First(&mission).Error != nil {
		return errors.New("抱歉,未找到任务信息"), 0
	}
	if mission.Status != 2 || mission.GoodsStatus != 1 {
		return errors.New("抱歉,当前任务不可领取"), 0
	}
	now := time.Now().UTC().Unix()
	if mission.StartTime.Unix() > now || mission.EndTime.Unix() < now {
		return errors.New("抱歉,不在任务领取时间内"), 0
	}

	if mission.HireType == 1 && mission.ClaimStock <= mission.ClaimNum {
		return errors.New("可接人数已满额"), 0
	}

	if mission.HireType == 2 {
		var total int64
		global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ? and hire_type = 2", uuid, mission.ID).Count(&total)
		if total >= 10 {
			return errors.New("进行中任务已达上限"), 0
		}
	}

	var address model.Address
	if !errors.Is(global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ?", uuid, info.MissionId).First(&model.MissionClaim{}).Error, gorm.ErrRecordNotFound) { // 判断email是否注册
		return errors.New("不可重复领取"), 0
	}
	if global.MG_DB.Model(&model.Address{}).Where("user_id = ? AND id = ?", uuid, info.AddressId).First(&address).Error != nil {
		return errors.New("抱歉,未找到地址信息"), 0
	}
	var (
		missionClaim           model.MissionClaim
		missionClaimOrder      model.MissionClaimOrder
		missionClaimOrderGoods model.MissionClaimOrderGoods
		missionClaimAddress    model.MissionClaimAddress
	)
	tx := global.MG_DB.Begin()
	missionClaim.MissionId = info.MissionId
	missionClaim.ClaimNo = utils.GetInvitationLowerLen(20)
	missionClaim.AchieveNum = 0
	missionClaim.CreateBy = uuid
	missionClaim.Status = 1
	expireDate := time.Now().AddDate(0, 0, mission.ClaimDays)
	missionClaim.ExpireAt = expireDate
	missionClaim.Email = info.Email //邮箱
	err = tx.Model(&model.MissionClaim{}).Create(&missionClaim).Error
	if err != nil {
		tx.Rollback()
		return
	}
	// 任务领取人数+1
	err = tx.Model(&model.Mission{}).Where("id = ?", info.MissionId).UpdateColumn("claim_num", gorm.Expr("`claim_num` + 1")).Error
	if err != nil {
		tx.Rollback()
		return
	}

	// 创建任务订单
	var (
		goods     model.TbGoods
		goodsSpec model.TbGoodsSpecs
	)
	err = tx.Model(&model.TbGoods{}).Where("online = 'on' AND spu_no = ?", info.SpuNo).First(&goods).Error
	if err != nil {
		tx.Rollback()
		err = errors.New("未找到商品信息")
		return
	}
	err = tx.Model(&model.TbGoodsSpecs{}).Where("status = 1 AND goods_id = ? AND sku_no = ?", goods.ID, info.SkuNo).First(&goodsSpec).Error
	if err != nil {
		tx.Rollback()
		err = errors.New("未找到商品规格信息")
		return
	}
	missionClaimOrder.OrderID = Generate()
	missionClaimOrder.MissionClaimId = missionClaim.ID
	missionClaimOrder.SpuNo = info.SpuNo
	missionClaimOrder.SkuNo = info.SkuNo
	missionClaimOrder.Number = 1
	missionClaimOrder.CreateBy = uuid
	missionClaimOrder.Status = 2 // 待发货
	err = tx.Model(&model.MissionClaimOrder{}).Create(&missionClaimOrder).Error
	if err != nil {
		tx.Rollback()
		err = errors.New("创建任务订单失败")
		return
	}
	missionClaimOrderGoods.OrderID = missionClaimOrder.OrderID
	missionClaimOrderGoods.SkuNo = info.SkuNo
	missionClaimOrderGoods.Title = goods.Title
	missionClaimOrderGoods.Image = goodsSpec.Image
	missionClaimOrderGoods.Specs = goodsSpec.Specs
	missionClaimOrderGoods.Price = goodsSpec.Price
	err = tx.Model(&model.MissionClaimOrderGoods{}).Create(&missionClaimOrderGoods).Error
	if err != nil {
		tx.Rollback()
		err = errors.New("创建任务订单失败")
		return
	}

	// 创建任务收获地址
	missionClaimAddress.Address = address
	missionClaimAddress.ID = 0
	missionClaimAddress.AddressId = address.ID
	missionClaimAddress.MissionClaimId = missionClaim.ID
	missionClaimAddress.OrderID = missionClaimOrder.OrderID
	err = tx.Model(&model.MissionClaimAddress{}).Create(&missionClaimAddress).Error
	if err != nil {
		tx.Rollback()
		return
	}

	_, seller := GetSellerStoreInfo(mission.CreateBy)

	if mission.HireType == 1 {
		// 固定佣金任务锁定商家营销账户
		var wallet model.Wallet
		err = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'seller' AND user_id = ?", seller.StoreNo).First(&wallet).Error
		if err != nil {
			return
		}
		var billFund model.BillFund
		billFund.UserID = mission.CreateBy
		billFund.TransactionType = 1
		billFund.TransactionId = "MB" + Generate() // mission-bill
		billFund.Title = ""
		billFund.Price = mission.HireMoney
		billFund.Balance = wallet.Fund
		billFund.Platform = "seller"
		billFund.RelatedId = missionClaim.ClaimNo
		billFund.Status = 1
		err = tx.Model(&model.BillFund{}).Create(&billFund).Error
		if err != nil {
			tx.Rollback()
			return
		}
	}
	tx.Commit()
	id = missionClaim.ID

	//给商家发送邮件
	go func(uid string, mission model.Mission, email string) {
		_, user := GetUserDetail(uid)
		body := fmt.Sprintf("您好,%s已被%s已接单,请及时回复网红疑问,促进网红完成任务", mission.Title, user.NickName)
		global.EMAIL_CLIENT.SendEmail(context.Background(), &api.SendRequest{
			To:      []string{email},
			Subject: "网红接任务",
			Body:    body,
		})
	}(uuid, mission, seller.Email)

	//给网红发送邮件
	if mission.HasVideo == 1 && mission.VideoUrl != "" {
		go func(mission model.Mission, email string, files string) {
			subject := fmt.Sprintf("任务《%s》素材已发送", mission.Title)
			body := "嗨,您接任务的素材已发送到邮箱,请查看,尽快完成任务。"
			global.EMAIL_CLIENT.SendEmail(context.Background(), &api.SendRequest{
				To:      []string{email},
				Subject: subject,
				Body:    body,
				Files:   []string{files},
			})
		}(mission, info.Email, mission.VideoUrl)
	}

	return
}

func SubmitClaimMissionWorks(uuid string, info request.ClaimMissionWorksList) (err error) {
	var (
		missionClaim model.MissionClaim
	)

	err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&missionClaim).Error
	if err != nil {
		err = errors.New("not found mission claim record")
		return err
	}

	tx := global.MG_DB.Begin()
	for i := 0; i < len(info.Works); i++ {
		var works model.MissionClaimWorks
		works.Type = info.Works[i].Type
		works.Homepage = info.Works[i].Homepage
		works.Image = info.Works[i].Image
		works.VideoUrl = info.Works[i].VideoUrl
		if info.Works[i].ID != 0 {
			if info.Works[i].Homepage == "" {
				err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Delete(&model.MissionClaimWorks{}).Error
				if err != nil {
					tx.Rollback()
					return err
				}
			} else {
				err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Select("Type", "Homepage", "Image", "VideoUrl").Updates(&works).Error
				if err != nil {
					tx.Rollback()
					return err
				}
			}
		} else {
			works.MissionClaimId = info.MissionClaimId
			err = tx.Model(&model.MissionClaimWorks{}).Create(&works).Error
			if err != nil {
				tx.Rollback()
				return err
			}
		}
	}
	claimStatus := 3 // 推广中
	err = tx.Model(&model.MissionClaim{}).Where("id = ? AND status = 2", info.MissionClaimId).UpdateColumn("status", claimStatus).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func SubmitClaimMissionVideo(uuid string, info request.ClaimMissionVideo) (err error) {
	var (
		mission      model.Mission
		missionClaim model.MissionClaim
		claimVideo   model.MissionClaimVideo
		achieveNum   int64
	)

	err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&missionClaim).Error
	if err != nil {
		err = errors.New("not found mission claim record")
		return err
	}
	err = global.MG_DB.Model(&model.Mission{}).Where("id = ?", missionClaim.MissionId).First(&mission).Error
	if err != nil {
		err = errors.New("not found mission record")
		return err
	}

	// 判断有无审核通过和待审核的
	err = global.MG_DB.Model(&model.MissionClaimVideo{}).Where("mission_claim_id = ? and status in (1,2)", info.MissionClaimId).First(&model.MissionClaimVideo{}).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("不能重复上传")
	}
	if info.SourceType == 2 {
		global.MG_DB.Model(&model.MissionClaimVideo{}).Where("create_by = ? and source_type = 2 and status in (1,2)", uuid).Count(&achieveNum)
	}

	tx := global.MG_DB.Begin()
	claimVideo.MissionClaimId = info.MissionClaimId
	claimVideo.VideoUrl = info.VideoUrl
	claimVideo.Cover = info.Cover
	claimVideo.Status = 1                         // 待审核
	claimVideo.SourceType = info.SourceType       // 来源类型
	claimVideo.MissionId = missionClaim.MissionId // 任务ID
	claimVideo.CreateBy = uuid                    // 创建者ID
	claimVideo.Width = info.Width                 //宽度
	claimVideo.Height = info.Height               //高度
	err = tx.Model(&model.MissionClaimVideo{}).Create(&claimVideo).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	// 完成平台任务奖励
	if info.SourceType == 2 {
		err = AddSysMissionReward(request.AddSysMissionReward{
			Type:       1,
			RelationId: strconv.Itoa(int(claimVideo.ID)),
			AchieveNum: achieveNum + 1,
			CreateBy:   uuid,
		}, tx)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	tx.Commit()
	return nil
}

// 查询任务奖金
func GetMissionBonus(code string) model.MissionBonus {
	var (
		bonus model.MissionBonus
	)
	global.MG_DB.Model(&model.Bill{}).Select("sum(bill.price) total").Joins("inner join `order` b on bill.order_id=b.order_id and b.code=?", code).Where("bill.status=2 and bill.type=1").Scan(&bonus)
	return bonus
}

func GetMissionStatusExcept(mission model.MissionDetail, uuid string) (except string) {
	if mission.Status != 2 {
		except = "当前时间,任务不可接"
		return except
	}
	if mission.HireType == 1 && mission.ClaimStock <= mission.ClaimNum {
		except = "可接人数已满额"
		return except
	}

	if !errors.Is(global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ?", uuid, mission.ID).First(&model.MissionClaim{}).Error, gorm.ErrRecordNotFound) { // 判断email是否注册
		return "任务已接"
	}

	if mission.HireType == 2 {
		var total int64
		global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ? and hire_type = 2", uuid, mission.ID).Count(&total)
		if total >= 10 {
			return "进行中任务已达上限"
		}
	}

	if mission.GoodsStatus != 1 {
		except = "商品已下架,任务不可接"
		return except
	}

	//费用待发放

	//费用已发放

	return ""
}

func GetMissionBonusAndSales(missionId uint) (model.MissionBonus, int64, int64) {
	var (
		claimList   []model.MissionClaim
		codes       []string
		achieveNums int64
		bonus       model.MissionBonus
		claimNum    int64
	)
	global.MG_DB.Model(&model.MissionClaim{}).Where("mission_id = ?", missionId).Find(&claimList)
	for _, vClaim := range claimList {
		codes = append(codes, vClaim.ClaimNo)
		achieveNums += vClaim.AchieveNum
	}
	claimNum = int64(len(claimList))

	global.MG_DB.Model(&model.Bill{}).Joins("INNER JOIN `order` ON `order`.order_id = bill.order_id").
		Select("SUM(bill.price) total,COUNT(DISTINCT bill.user_id) user_total").Where("bill.status=2 and bill.type=1 and `order`.`code` IN (?)", codes).Scan(&bonus)
	return bonus, achieveNums, claimNum
}

func getMissionClaimRewardUnfinished(uuid string) (error, float64) {
	var (
		err    error
		result float64
	)
	err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ?", uuid).Select("SUM(reward_unfinished) as reward_unfinished").Scan(&result).Error
	return err, result
}

func GetMissionClaimStatusExcept(res model.MissionClaimDetail) string {
	var (
		statusExcept string
	)
	switch res.Status {
	//状态 1:已领取待发货 2:已发货 3:已收货推广中
	case 1:
		statusExcept = "等待样品发货"
	case 2:
		statusExcept = "等待链接上传"
		if res.Mission.HireType == 1 {
			if res.Video.ID == 0 {
				statusExcept = "等待视频上传"
			} else {
				switch res.Video.Status {
				case 1:
					statusExcept = "等待视频审核"
				case 2:

				case 3:
					statusExcept = "视频审核不通过"
				}
			}
		}
	case 3:
		statusExcept = "链接已上传"
		//todo 查看奖励发放状态
		if res.Mission.HireType == 1 {
			switch res.Video.RewardStatus {
			case 1:
				statusExcept = "费用待发放"
			case 2:
				statusExcept = "费用已发放"
			}
		}
	}

	return statusExcept
}