package talent_service

import (
	"context"
	"fmt"
	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gtime"
	"youngmini_server/app/dao"
	"youngmini_server/app/model"
	"youngmini_server/app/model/talent_model"
	"youngmini_server/app/utils"
)

type platformExamineState int
const (
	waitForExamine platformExamineState = iota + 1
	examineSuccess
	examineFailed
)

const buySamplesTypeYounggee = 1

// GetOrderList 获取达人已接订单列表，如果有search_name参数则根据此信息对已接订单进行搜索，否则获取所有已接订单
func GetOrderList(r *ghttp.Request) *TalentHttpResult {
	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
	if err != nil {
		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
	}

	taskOrBrandName := r.GetQueryString("search_name", "nil")


	whereStr := fmt.Sprintf("talent_id = %d", tid)
	if taskOrBrandName != "nil" {
		taskOrBrandName = "%" + taskOrBrandName + "%"
		whereStr += " and (task_name like '" + taskOrBrandName + "' or task_brand_name like '" + taskOrBrandName + "')"
	}

	var orderList []*model.OrderInfo
	err = g.DB().Model(dao.OrderInfo.Table).Where(whereStr).
		Order(dao.OrderInfo.Columns.CompleteStatus).Scan(&orderList)
	if err != nil {
		return &TalentHttpResult{Code: -2, Msg: "get order info failed"}
	}

	classifiedOrderList := talent_model.ClassifiedOrderInfoBriefList{}
	for _, v := range orderList {
		// 获取任务招募等级信息
		levelRec, err1 := g.DB().Model(dao.TaskRecruitTalentLevel.Table).Where("trt_id", v.TaskLevelId).One()
		if err1 != nil || levelRec == nil {
			return &TalentHttpResult{Code: -4, Msg: "query task level failed"}
		}

		// 获取任务信息
		taskRec, err1 := g.DB().Model(dao.TaskBaseInfo.Table).Where("task_id", v.TaskId).One()
		if err1 != nil || taskRec == nil {
			return &TalentHttpResult{Code: -5, Msg: "query task info failed"}
		}

		// 获取任务关联的商品的主图
		productPhoto, err1 := g.DB().Model(dao.ProductPhoto.Table).One("product_id = ? and symbol = 1", taskRec[dao.TaskBaseInfo.Columns.ProductId])
		if err1 != nil {
			return &TalentHttpResult{Code: -6, Msg: "query product photo info failed"}
		}

		// 获取平台信息
		platRec, err1 := g.DB().Model(dao.InfoThirdPlatform.Table).One("platform_id", taskRec[dao.TaskBaseInfo.Columns.TaskPlatform].Int())
		if err1 != nil || platRec == nil {
			return &TalentHttpResult{Code: -7, Msg: "query platform info failed"}
		}

		// 获取平台昵称
		nickNameRet, err1 := g.DB().Model(platRec[dao.InfoThirdPlatform.Columns.PlatformTableName].String()).
			Fields("platform_nickname").
			Where("talent_id", v.TalentId).One()
		if err1 != nil || nickNameRet == nil {
			return &TalentHttpResult{Code: -8, Msg: "query platform nickname failed"}
		}

		// 获取订单执行进度
		procedureRec, err1 := g.DB().Model(dao.WorkflowNodeContainer.Table).
			One("order_id = ? and sort_id = ?", v.OrderId, v.OrderStatus)
		if err1 != nil || procedureRec == nil {
			return &TalentHttpResult{Code: -9, Msg: "query order procedure info failed"}
		}

		var procedureName string
		if procedureRec[dao.WorkflowNodeContainer.Columns.CurExecutionTimes].Int() < 2 {
			procedureName = procedureRec[dao.WorkflowNodeContainer.Columns.NodeNameFirst].String()
		} else {
			procedureName = procedureRec[dao.WorkflowNodeContainer.Columns.NodeNameAfterSecond].String()
		}

		orderInfoBrief := &talent_model.OrderInfoBrief{
			OrderId: v.OrderId,
			PlatformIconUrl: platRec[dao.InfoThirdPlatform.Columns.PlatformIcon].String(),
			PlatformName: platRec[dao.InfoThirdPlatform.Columns.PlatformName].String(),
			PlatformNickName: nickNameRet["platform_nickname"].String(),
			OrderProcedure: procedureName,
			TaskName: taskRec[dao.TaskBaseInfo.Columns.TaskName].String(),
			RecruitLevel: levelRec,
			ProcedureNote: procedureRec[dao.WorkflowNodeContainer.Columns.Tip].String(),
			ProductImgUrl: productPhoto[dao.ProductPhoto.Columns.PhotoUrl].String(),
			OrderCompleteStatus: v.CompleteStatus,
			OrderCompleteDate: v.CompleteDate,
		}

		classifiedOrderList.AllOrderInfoList = append(classifiedOrderList.AllOrderInfoList, orderInfoBrief)

		if v.CompleteStatus < 2 {
			if v.OrderStatus == 1 {
				classifiedOrderList.SelectOrderInfoList = append(classifiedOrderList.SelectOrderInfoList, orderInfoBrief)
			}

			if v.OrderStatus > 1 {
				classifiedOrderList.GoingOnOrderInfoList = append(classifiedOrderList.GoingOnOrderInfoList, orderInfoBrief)
			}
		} else {
			classifiedOrderList.CompletedOrderInfoList = append(classifiedOrderList.CompletedOrderInfoList, orderInfoBrief)
		}
	}

	return &TalentHttpResult{Code: 0, Msg: "success", Data: classifiedOrderList}
}

// GetOrderDetail 获取订单详情
func GetOrderDetail(r *ghttp.Request) *TalentHttpResult {
	orderId := r.GetQueryInt("oid", 0)
	if orderId == 0 {
		return &TalentHttpResult{Code: -1, Msg: "未找到订单号信息"}
	}

	var orderDetail *talent_model.OrderDetailInfo
	err := g.DB().Model(dao.OrderInfo.Table).WithAll().Scan(&orderDetail, dao.OrderInfo.Columns.OrderId, orderId)
	if err != nil {
		return &TalentHttpResult{Code: -2, Msg: "查询数据失败"}
	}

	//if orderDetail.TaskInfo.Conditions.BuySamplesType == buySamplesTypeYounggee {
	//	// 拍单方式为样叽拍单，获取拍单详细信息
	//	rec, err1 := g.DB().Model(dao.TaskProcedureBuySamplesInfo.Table).One(dao.TaskProcedureBuySamplesInfo.Columns.TaskBaseId, orderDetail.TaskId)
	//	if err1 != nil {
	//		return &TalentHttpResult{Code: -3, Msg: "查询拍单信息失败"}
	//	}
	//
	//	orderDetail.BuySamplesInfo = rec
	//} else {
	//	orderDetail.BuySamplesInfo = nil
	//}

	return &TalentHttpResult{Code: 0, Msg: "success", Data: orderDetail}
}

// SignupTask 达人报名任务(产生订单)
func SignupTask(r *ghttp.Request) *TalentHttpResult {
	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
	if err != nil {
		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
	}

	// 获取达人信息
	talentRec, err := g.DB().Model(dao.TalentInfo.Table).One("id", tid)
	if err != nil || talentRec == nil {
		return &TalentHttpResult{Code: -13, Msg: "query talent info failed"}
	}

	// 如果达人在黑名单则不允许报名
	if talentRec[dao.TalentInfo.Columns.InBlacklist].Int() >= 1 {
		return &TalentHttpResult{Code: -2, Msg: "talent in blacklist"}
	}

	var signupInfo *talent_model.SignupInfo
	err = r.ParseForm(&signupInfo)
	if err != nil {
		return &TalentHttpResult{Code: -3, Msg: err.Error()}
	}

	taskId := signupInfo.TaskId

	var taskDetail *talent_model.TaskDetail
	err = g.DB().Model(talent_model.TaskDetail{}).WithAll().Where("task_id", taskId).Scan(&taskDetail)
	if err != nil {
		return &TalentHttpResult{Code: -4, Msg: "data query failed"}
	}

	// 校验任务是否已过报名截止时间
	if taskDetail.DeadlineTime.Before(gtime.Now()) {
		return &TalentHttpResult{Code: -5, Msg: "task has close sign up"}
	}

	// 校验达人是否已经报名过该任务
	rec, err := g.DB().Model(dao.OrderInfo.Table).One("task_id = ? and talent_id = ?", taskId, tid)
	if err != nil || rec != nil {
		return &TalentHttpResult{Code: -6, Msg: "talent have signed up task"}
	}

	// 校验达人是否拥有任务要求的平台账号
	rec, err = g.DB().Model(dao.RTalentPlatformTable.Table).One("tid = ? and p_id = ?", tid, taskDetail.TaskPlatform)
	if err != nil {
		return &TalentHttpResult{Code: -7, Msg: "query talent platform info failed"}
	}

	// 达人没有任务要求的平台账号，返回
	if rec == nil {
		return &TalentHttpResult{Code: -8, Msg: "talent have no platform account"}
	}

	// 达人平台账号审核未通过，返回
	if rec[dao.RTalentPlatformTable.Columns.ExamineState].Int() != int(examineSuccess) {
		return &TalentHttpResult{Code: -9, Msg: "talent platform account examine failed"}
	}


	// 获取任务要求的平台对应的平台信息
	rec, err = g.DB().Model(dao.InfoThirdPlatform.Table).One(dao.InfoThirdPlatform.Columns.PlatformId, taskDetail.TaskPlatform)
	if err != nil || rec == nil {
		return &TalentHttpResult{Code: -10, Msg: "query platform table name failed"}
	}

	// 获取达人的平台账号信息
	platformRec, err := g.DB().Model(rec[dao.InfoThirdPlatform.Columns.PlatformTableName].String()).One("talent_id", tid)
	if err != nil || platformRec == nil {
		return &TalentHttpResult{Code: -11, Msg: "query talent platform info failed"}
	}

	var remuneration int64
	found := false
	for _, v := range taskDetail.NeedTalentCount {
		if v.TrtId == signupInfo.TaskRecruitLevelId {
			if platformRec["fans_count"].Int() < v.FansCountMin {
				return &TalentHttpResult{Code: -12, Msg: "fans count not match recruit level"}
			}

			remuneration = v.RewardRoyalties
			found = true
			break
		}
	}

	if !found {
		return &TalentHttpResult{Code: -13, Msg: "recruit level info error"}
	}
	//// 校验达人粉丝数量是否符合要求
	//if platformRec["fans_count"].Int() < taskDetail.NeedTalentCount[signupInfo.TaskRecruitLevelId].FansCountMin {
	//	return &TalentHttpResult{Code: -10, Msg: "fans count not match recruit level"}
	//}


	// 获取收货地址信息
	var addrInfo *model.TalentDeliveryAddress
	err = g.DB().Model(dao.TalentDeliveryAddress.Table).
		Where(dao.TalentDeliveryAddress.Columns.AddressId, signupInfo.DeliveryAddrId).Scan(&addrInfo)
	if err != nil || addrInfo == nil {
		return &TalentHttpResult{Code: -14, Msg: "query delivery address failed"}
	}

	// 生成达人平台账号信息和达人信息的快照
	platformSnap, err := gjson.Encode(platformRec)
	if err != nil {
		return &TalentHttpResult{Code: -15, Msg: "encode platform snap failed"}
	}

	// 生成达人信息快照
	talentSnap, err := gjson.Encode(talentRec)
	if err != nil {
		return &TalentHttpResult{Code: -16, Msg: "encode talent info snap failed"}
	}

	// 生成收货地址快照
	addrSnap, err := gjson.Encode(addrInfo)
	if err != nil {
		return &TalentHttpResult{Code: -17, Msg: "encode delivery address snap failed"}
	}

	var productMainImg string
	for _, v := range taskDetail.ProductInfo.ProductImages {
		if productMainImg == "" {
			productMainImg = v.PhotoUrl
		}

		if v.Symbol == 1 {
			productMainImg = v.PhotoUrl
			break
		}
	}
	err = g.DB().Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
		// 报名信息存入报名信息(订单)表
		orderId, err1 := tx.Ctx(ctx).Model(dao.OrderInfo.Table).Data(model.OrderInfo{
			TaskId:                 taskId,
			TaskName:               taskDetail.TaskName,
			TaskBrandName:          taskDetail.TaskBrandInfo.BrandName,
			ProductName:            taskDetail.ProductInfo.ProductName,
			ProductMainImg:         productMainImg,
			TalentId:               tid,
			TalentPlatformInfoSnap: string(platformSnap),
			TalentPersonalInfoSnap: string(talentSnap),
			TalentPostAddrSnap:     string(addrSnap),
			TaskLevelId:            signupInfo.TaskRecruitLevelId,
			SettleAmount: 			remuneration,
			ProdSpecificationId:    signupInfo.ProductSpecificationIndex,
			ProdNote:               signupInfo.ProductNote,
			OrderStatus:            1,
			CompleteStatus:         1,
			CreateDate:             gtime.Now(),
		}).InsertAndGetId()
		if err1 != nil {
			return err1
		}

		// 产生订单流程
		err1 = utils.OrderProcedureManager.GenOrderWorkflowList(taskId, int(orderId), ctx, tx)
		if err1 != nil {
			return err1
		}

		// 将达人收货信息写入order_delivery_info表，供后台查看和操作
		_, err1 = tx.Ctx(ctx).Model(dao.OrderDeliveryInfo.Table).Insert(model.OrderDeliveryInfo{
			OrderId:          orderId,
			OrderAddressee:   addrInfo.ReceiverName,
			OrderPhone:       addrInfo.PhoneNumber,
			RegionCode:       addrInfo.RegionCode,
			OrderAddress:     addrInfo.DetailAddr,
			LogisticsCompany: "",
			TrackingNum:      "",
			CreatedAt:        gtime.Now(),
			ConfirmTime:      nil,
			DeliveryTime:     nil,
			DeliveryStatus:   1,
		})
		if err1 != nil {
			return err1
		}

		// 将订单状态插入订单状态表
		_, err1 = tx.Ctx(ctx).Model(dao.OrderStatusRecord.Table).Insert(model.OrderStatusRecord{
			OrderId:       int(orderId),
			AlterBefore:   0,
			AlterAfter:    1,
			RoleTag:       2,
			RecordId:      tid,
			RecordName:    talentRec[dao.TalentInfo.Columns.TalentWxNickname].String(),
			CreatedAt:     gtime.Now(),
		})

		return err1
	})

	if err != nil {
		return &TalentHttpResult{Code: -18, Msg: "add order data failed"}
	}

	return &TalentHttpResult{Code: 0, Msg: "success"}
}

// GetOrderSignUpPlatformInfo 获取报名信息里的平台信息快照
func GetOrderSignUpPlatformInfo(r *ghttp.Request) *TalentHttpResult {
	orderId := r.GetQueryInt("order_id", 0)
	if orderId == 0 {
		return &TalentHttpResult{Code: -1, Msg: "need order id"}
	}

	rec, err := g.DB().Model(dao.OrderInfo.Table).Fields(dao.OrderInfo.Columns.TalentPlatformInfoSnap).One(dao.OrderInfo.Columns.OrderId, orderId)
	if err != nil || rec == nil {
		return &TalentHttpResult{Code: -2, Msg: "query order info failed"}
	}


	return &TalentHttpResult{Code: 0, Msg: "success", Data: rec[dao.OrderInfo.Columns.TalentPlatformInfoSnap]}
}

// GetOrderBriefInfo 获取订单帮助信息里的brief列表
func GetOrderBriefInfo(r *ghttp.Request) *TalentHttpResult {
	orderId := r.GetQueryInt("order_id", 0)
	if orderId == 0 {
		return &TalentHttpResult{Code: -1, Msg: "must input order id"}
	}

	var briefList *talent_model.OrderBriefInfo
	err := g.DB().Model(dao.OrderInfo.Table).WithAll().Scan(&briefList, dao.OrderInfo.Columns.OrderId, orderId)
	if err != nil {
		return &TalentHttpResult{Code: -2, Msg: "query data failed"}
	}

	return &TalentHttpResult{Code: 0, Msg: "success", Data: briefList}
}