package sectask_service

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/issue9/conv"
	"github.com/sirupsen/logrus"
	"strconv"
	"time"
	"youngee_b_api/db"
	"youngee_b_api/model/gorm_model"
	"youngee_b_api/model/http_model"
)

var SelectionTask *selectionTask

type selectionTask struct {
}

func (*selectionTask) GetList(ctx context.Context, request http_model.GetSecTaskListRequest) (*http_model.GetSecTaskListData, error) {
	// sec_task：任务id、帐号昵称、粉丝数、收货地址、主页截图、主页链接、确认时间、申请时间、结算时间
	// youngee_task_logistics： 物流公司、物流单号、发货时间、探店时间
	// younggee_assignment_info：数据截图、作业链接
	// selection_info: 返现金额、悬赏金额
	// 1. 根据选品任务阶段、账号昵称or任务id查询任务基本信息（包括任务id、账号昵称、粉丝数、主页截图、主页链接、申请时间）
	secTaskList, total, err := db.GetSecTaskList(ctx, request.SelectionId, request.SecTaskStatus, request.SearchValue, request.PageSize, request.PageNum)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskList error,err:%+v", err)
		return nil, err
	}

	// 2. 根据不同查询类型查询补充信息
	switch request.Type {
	case 1: // 确定达人查询
		// 确定达人不需要额外信息
		break
	case 2: // 发货管理查询 youngee_task_logistics
		//发货管理根据任务阶段和商品类型查询物流信息
		// 查询商品类型
		product, err := db.GetProductType(ctx, request.SelectionId)
		if err != nil {
			logrus.WithContext(ctx).Errorf("[sectask_service service] call GetAllSelection error,err:%+v", err)
			return nil, err
		}
		secTaskList, err = db.GetSecTaskLogisticsList(ctx, secTaskList, request.SecTaskStatus, *product)
		if err != nil {
			logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskLogisticsList error,err:%+v", err)
			return nil, err
		}
		break
	case 3: // 结算管理查询 younggee_assignment_info
		secTaskList, err = db.GetSecTaskSettleList(ctx, secTaskList, request.SelectionId, request.SecTaskStatus)
		if err != nil {
			logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskSettleList error,err:%+v", err)
			return nil, err
		}
		break
	default: // 参数有误
		break
	}

	selectionListData := http_model.GetSecTaskListData{
		Total:       conv.MustString(total, ""),
		SecTaskList: secTaskList,
	}

	return &selectionListData, nil
}

func (*selectionTask) PassCoop(ctx context.Context, request http_model.PassSecTaskCoopRequest) (*http_model.PassSecTaskCoopData, error) {
	_, err := db.PassSecTaskCoop(ctx, request.SelectionId, request.TaskIds)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call PassCoop error,err:%+v", err)
		return nil, err
	}

	selectionListData := http_model.PassSecTaskCoopData{}

	return &selectionListData, nil
}

func (*selectionTask) RefuseCoop(ctx context.Context, request http_model.RefuseSecTaskCoopRequest) (*http_model.RefuseSecTaskCoopData, error) {

	_, err := db.RefuseSecTaskCoop(ctx, request.TaskIds)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call RefuseCoop error,err:%+v", err)
		return nil, err
	}

	selectionListData := http_model.RefuseSecTaskCoopData{}

	return &selectionListData, nil
}

func (*selectionTask) Settle(ctx context.Context, entersizeId string, request http_model.SettleSecTaskRequest) (*http_model.SettleSecTaskData, error) {
	// 1. 解析request data
	var returnMoney float64 = 0.0
	var rewardMoney float64 = 0.0
	payMoney, err := strconv.ParseFloat(request.TotalPayMoney, 64)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err)
		return nil, err
	}
	// 2. 校验：任务是否正常（处于待结算阶段）；企业账户可用余额是否充足；若返现则校验达人是否垫付买样；若有悬赏金额则校验是否为悬赏任务
	// 1) 校验企业账户余额是否充足
	entersize, err := db.GetEnterpriseByEnterpriseID(ctx, entersizeId)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetEnterpriseByEnterpriseID error,err:%+v", err)
		return nil, err
	}
	if entersize.AvailableBalance < payMoney {
		return nil, errors.New("账户余额不足")
	}
	// 2) 若返现则校验达人是否垫付买样；若有悬赏金额则校验是否为悬赏任务
	selection, err := db.GetSelectionById(ctx, request.SelectionID)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSelectionById error,err:%+v", err)
		return nil, err
	}
	if selection.SampleMode != 2 && request.IsReturnMoney == 1 {
		return nil, errors.New("免费领养任务不能返样品钱")
	}
	if selection.TaskMode != 1 && request.IsPayReward == 1 {
		return nil, errors.New("非悬赏任务不能支付悬赏")
	}
	// 3) 校验任务是否处于待结算阶段
	secTask, err := db.GetSecTaskById(ctx, request.TaskID)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskById error,err:%+v", err)
		return nil, err
	}
	if secTask.TaskStage != 9 && secTask.TaskStatus != 2 {
		return nil, errors.New("该任务暂不可结算")
	}

	var product gorm_model.YounggeeProduct
	if err = json.Unmarshal([]byte(selection.ProductSnap), &product); err != nil {
		fmt.Println("Error:", err)
		return nil, err
	}
	// 4) 校验结算金额计算是否正确
	if request.IsReturnMoney == 1 {
		returnMoney = product.ProductPrice
	}
	if request.IsPayReward == 1 {
		rewardMoney, err = strconv.ParseFloat(selection.TaskReward, 64)
		if err != nil {
			logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err)
			return nil, err
		}
	}
	if rewardMoney+returnMoney != payMoney {
		return nil, errors.New("结算金额有误")
	}

	// 3. 更新选品结算金额
	_, err = db.UpdateSelectionSettleMoney(ctx, selection.SelectionID, payMoney)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateSelectionSettleMoney error,err:%+v", err)
		return nil, err
	}

	// 4. 更新选品任务阶段
	updateSecTaskData := gorm_model.YounggeeSecTaskInfo{
		TaskID:           request.TaskID,
		TaskStage:        10,
		AssignmentStatus: 5,
		IsPayReward:      request.IsPayReward,
		IsPayPayment:     request.IsReturnMoney,
		CompleteDate:     time.Now(),
	}
	_, err = db.UpdateSecTask(ctx, updateSecTaskData)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateSecTask error,err:%+v", err)
		return nil, err
	}

	// 5. 添加任务日志和达人消息
	err = db.CreateTaskLog(ctx, request.TaskID, "结算时间")
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateTaskLog error,err:%+v", err)
		return nil, err
	}

	err = db.CreateMessageBySecTaskId(ctx, 5, 1, request.TaskID)
	if err != nil {
		logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateMessageBySecTaskId error,err:%+v", err)
		return nil, err
	}

	// 6. 创建选品收益记录
	// 返现收益
	var productPhotoStruct []gorm_model.YounggeeProductPhoto
	if err = json.Unmarshal([]byte(selection.ProductPhotoSnap), &productPhotoStruct); err != nil {
		fmt.Println("Error:", err)
		return nil, err
	}
	var mainPhoto = ""
	for _, w := range productPhotoStruct {
		if w.Symbol == 1 {
			mainPhoto = w.PhotoUrl
		}
	}
	t := time.Now()
	if request.IsReturnMoney == 1 {
		income := gorm_model.YounggeeTalentIncome{
			TalentID:       secTask.TalentID,
			SelectionID:    secTask.SelectionID,
			SectaskID:      secTask.TaskID,
			Type:           2,
			BrandName:      product.BrandName,
			TaskName:       selection.SelectionName,
			PhotoUrl:       mainPhoto,
			Income:         strconv.FormatFloat(returnMoney, 'f', 10, 32),
			IncomeType:     3,
			WithdrawStatus: 1,
			IncomeAt:       &t,
			WithdrawAt:     nil,
		}
		err = db.CreateIncome(ctx, income, nil)
		if err != nil {
			logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err)
			return nil, err
		}
	}
	// 悬赏收益
	if request.IsPayReward == 1 {
		income := gorm_model.YounggeeTalentIncome{
			TalentID:       secTask.TalentID,
			SelectionID:    secTask.SelectionID,
			SectaskID:      secTask.TaskID,
			Type:           2,
			BrandName:      product.BrandName,
			TaskName:       selection.SelectionName,
			PhotoUrl:       mainPhoto,
			Income:         strconv.FormatFloat(rewardMoney, 'f', 10, 32),
			IncomeType:     4,
			WithdrawStatus: 1,
			IncomeAt:       &t,
			WithdrawAt:     nil,
		}
		err = db.CreateIncome(ctx, income, nil)
		if err != nil {
			logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err)
			return nil, err
		}
	}

	// 7. 若有young之团存在，则为young之团创建收益

	settleSecTaskData := http_model.SettleSecTaskData{}

	return &settleSecTaskData, nil
}
