package platform

import (
	"applet/app/db"
	"applet/app/db/model"
	offical "applet/app/db/official"
	"applet/app/e"
	"applet/app/utils"
	"applet/app/utils/cache"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"time"
)

func WithdrawalIncome(c *gin.Context) {
	args, mid, err := commArg(c)
	if err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	fmt.Println(args)
	fmt.Println(mid)
	if args["type"] == "" {
		args["type"] = "playlet"
	}
	amountMap := masterAmount(mid, args["type"])
	monthAmountMap := masterMonthAmount(mid)
	isNeedBingAlipay := "1"
	if amountMap["alipay"] != "" {
		isNeedBingAlipay = "0"
	}
	var res = make([]map[string]string, 0)
	if amountMap["is_show_official_amount"] == "1" {
		var tmp = map[string]string{"name": "账户一余额", "value": amountMap["amount"], "type": "amount", "tip": "", "alipay": amountMap["alipay"], "alipay_name": amountMap["alipay_name"], "is_need_bing_alipay": isNeedBingAlipay, "is_show_withdrawal": "1"}
		res = append(res, tmp)
		if amountMap["is_show_agent_amount"] == "1" {
			var tmpAgent = map[string]string{"name": "账户二余额", "value": amountMap["agent_amount"], "type": "agent_amount", "tip": "", "alipay": amountMap["alipay"], "alipay_name": amountMap["alipay_name"], "is_need_bing_alipay": isNeedBingAlipay, "is_show_withdrawal": "1"}
			res = append(res, tmpAgent)
		}
	} else {
		var tmpAgent = map[string]string{"name": "账户二余额", "value": amountMap["agent_amount"], "type": "agent_amount", "tip": "", "alipay": amountMap["alipay"], "alipay_name": amountMap["alipay_name"], "is_need_bing_alipay": isNeedBingAlipay, "is_show_withdrawal": "1"}
		res = append(res, tmpAgent)
	}
	res = append(res, map[string]string{"name": "上月预估收益", "value": monthAmountMap["last_month_amount"], "type": "last_month_amount", "tip": "", "is_need_bing_alipay": "0", "is_show_withdrawal": "0"})
	res = append(res, map[string]string{"name": "上月预估结算收益", "value": amountMap["last_month_settle_amount"], "type": "last_month_settle_amount", "tip": "", "is_need_bing_alipay": "0", "is_show_withdrawal": "0"})
	res = append(res, map[string]string{"name": "本月预估收益", "value": monthAmountMap["month_amount"], "type": "month_amount", "tip": "", "is_need_bing_alipay": "0", "is_show_withdrawal": "0"})
	res = append(res, map[string]string{"name": "本月预估结算收益", "value": monthAmountMap["month_settle_amount"], "type": "month_settle_amount", "tip": "", "is_need_bing_alipay": "0", "is_show_withdrawal": "0"})

	e.OutSuc(c, res, nil)
	return
}
func WithdrawalList(c *gin.Context) {
	args, mid, err := commArg(c)
	if err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	amountMap := masterAmount(mid, args["type"])
	masterWithdrawalFlowDb := db.MasterWithdrawalFlowDb{}
	masterWithdrawalFlowDb.Set()
	list, total := masterWithdrawalFlowDb.GetWithdrawalFlowListWithTotal(amountMap["id"], args)
	data := make([]map[string]string, 0)
	if list != nil {
		for _, v := range *list {
			var tmp = map[string]string{
				"id":                     utils.IntToStr(v.Id),
				"alipay":                 v.Alipay,
				"alipay_name":            v.AlipayName,
				"amount":                 v.Amount,
				"real_amount":            v.RealAmount,
				"fee":                    v.Fee,
				"time":                   v.Time.Format("2006-01-02 15:04:05"),
				"check_time":             "",
				"status":                 v.Status,
				"remark":                 v.Remark,
				"reason":                 v.Reason,
				"img":                    v.Img,
				"is_need_upload_invoice": utils.IntToStr(v.HasInvoice),
			}
			if v.Img != "" {
				tmp["is_need_upload_invoice"] = "0"
			}
			if v.CheckTime.IsZero() == false {
				tmp["check_time"] = v.CheckTime.Format("2006-01-02 15:04:05")
			}
			data = append(data, tmp)
		}
	}
	statusList := []map[string]string{
		{"name": "提现审核", "value": "提现审核"},
		{"name": "提现成功", "value": "提现成功"},
		{"name": "提现失败", "value": "提现失败"},
	}
	var res = map[string]interface{}{
		"list": data, "total": total, "status_list": statusList,
	}
	e.OutSuc(c, res, nil)
	return
}
func WithdrawalDoing(c *gin.Context) {
	args, mid, err := commArg(c)
	if err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	if utils.StrToFloat64(args["amount"]) <= 0 {
		e.OutErr(c, 400, e.NewErr(400, "金额不正确"))
		return
	}
	masterdb := db.MasterDb{}
	masterdb.Set()
	master := masterdb.GetMaster(mid)
	if master == nil {
		e.OutErr(c, 400, e.NewErr(400, "用户不存在"))
		return
	}
	amountMap := masterAmount(mid, args["type"])
	puid := "0"
	if args["amount_type"] == "agent_amount" {
		amountMap["amount"] = amountMap["agent_amount"]
		amountMap["list_id"] = amountMap["agent_list_id"]
		puid = amountMap["puid"]
	}
	leaveAmount := utils.StrToFloat64(amountMap["amount"]) - utils.StrToFloat64(args["amount"])
	if leaveAmount < 0 {
		e.OutErr(c, 400, e.NewErr(400, "余额不足"))
		return
	}
	masterListCfgDb := db.MasterListCfgDb{}
	masterListCfgDb.Set()
	withdrawalBili := masterListCfgDb.MasterListCfgGetOneData(puid, "withdrawal_bili")
	invoiceBili := masterListCfgDb.MasterListCfgGetOneData(puid, "invoice_bili")
	withdrawalDay := masterListCfgDb.MasterListCfgGetOneData(puid, "withdrawal_day")
	if time.Now().Day() != utils.StrToInt(withdrawalDay) && utils.StrToInt(withdrawalDay) > 0 {
		e.OutErr(c, 400, e.NewErr(400, "每月"+withdrawalDay+"号提现"))
		return
	}
	var fee float64 = 0
	if utils.StrToFloat64(withdrawalBili) > 0 {
		bili := utils.StrToFloat64(withdrawalBili) / 100
		var invoiceBiliMap = make([]string, 0)
		json.Unmarshal([]byte(invoiceBili), &invoiceBiliMap)
		if utils.InArr(args["invoice_bili"], invoiceBiliMap) == false && utils.StrToInt(args["has_invoice"]) == 1 {
			e.OutErr(c, 400, e.NewErr(400, "发票税率不正确"))
			return
		}
		//开了发票的话再扣掉对应的发票比例
		if utils.InArr(args["invoice_bili"], invoiceBiliMap) && utils.StrToInt(args["has_invoice"]) == 1 {
			bili -= utils.StrToFloat64(args["invoice_bili"]) / 100
		}
		fee = utils.StrToFloat64(args["amount"]) * bili
	}
	realAmount := utils.StrToFloat64(args["amount"]) - fee
	if amountMap["alipay"] == "" {
		e.OutErr(c, 400, e.NewErr(400, "未绑定支付宝"))
		return
	}

	mutexKey := fmt.Sprintf("withdrawal:%s", amountMap["id"])
	withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 30, "NX")
	if err != nil {
		e.OutErr(c, e.ERR, err)
		return
	}
	if withdrawAvailable != "OK" {
		e.OutErr(c, e.ERR, e.NewErr(400000, "操作过于频繁,请稍后再试"))
		return
	}
	sess := db.ZhimengDb.NewSession()
	err = sess.Begin()
	if err != nil {
		sess.Rollback()
		e.OutErr(c, 400, e.NewErr(400000, "请重试"))
		return
	}
	defer sess.Close()

	//先扣钱
	amountData := db.GetMasterAmountByListIdWithSess(sess, amountMap["list_id"])
	if amountData == nil {
		sess.Rollback()
		e.OutErr(c, e.ERR, e.NewErr(400000, "提现失败"))
		return
	}
	oldAmount := amountData.Amount
	leaveAmount = utils.StrToFloat64(amountData.Amount) - utils.StrToFloat64(args["amount"])
	if leaveAmount < 0 {
		e.OutErr(c, 400, e.NewErr(400, "余额不足"))
		return
	}
	amountData.Amount = utils.Float64ToStr(leaveAmount)
	update := db.MasterAmountUpdateWithSess(sess, amountData.Id, amountData)
	if update == false {
		e.OutErr(c, e.ERR, e.NewErr(400000, "提现失败"))
		return
	}
	//再写入明细
	var tmpFlow = model.MasterAmountFlow{
		Uid:          amountMap["id"],
		Time:         time.Now(),
		BeforeAmount: oldAmount,
		Amount:       args["amount"],
		AfterAmount:  amountData.Amount,
		Platform:     args["type"],
		Oid:          "",
		Title:        "提现",
		FlowType:     "withdrawal",
		ExtendUid:    puid,
	}
	flowInsert := db.MasterAmountFlowInsertWithSess(sess, &tmpFlow)
	if flowInsert == false {
		e.OutErr(c, e.ERR, e.NewErr(400000, "提现失败"))
		return
	}
	var tmp = model.MasterWithdrawalFlow{
		Uid:         amountMap["id"],
		Time:        time.Now(),
		UpdateTime:  time.Now(),
		Remark:      args["remark"],
		Alipay:      amountMap["alipay"],
		AlipayName:  amountMap["alipay_name"],
		Amount:      args["amount"],
		RealAmount:  utils.Float64ToStr(realAmount),
		Fee:         utils.Float64ToStr(fee),
		Reason:      "",
		Status:      "提现审核",
		HasInvoice:  utils.StrToInt(args["has_invoice"]),
		InvoiceBili: args["invoice_bili"],
		ExtendUid:   puid,
	}
	insert := db.MasterWithdrawalFlowInsertWithSess(sess, &tmp)
	if insert == false {
		e.OutErr(c, e.ERR, e.NewErr(400000, "提现失败"))
		return
	}
	sess.Commit()
	e.OutSuc(c, "success", nil)
	return
}
func WithdrawalOutput(c *gin.Context) {
	args, mid, err := commArg(c)
	if err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	args["size"] = "3000"
	amountMap := masterAmount(mid, args["type"])
	masterWithdrawalFlowDb := db.MasterWithdrawalFlowDb{}
	masterWithdrawalFlowDb.Set()
	list := masterWithdrawalFlowDb.GetWithdrawalFlowList(amountMap["id"], args)
	name := "订单_" + args["p"]
	//写入数据
	data := map[string]string{
		"A1": "提现支付宝账号",
		"B1": "提现支付宝姓名",
		"C1": "提现金额",
		"D1": "实际金额",
		"E1": "手续费",
		"F1": "提现状态",
		"G1": "申请时间",
		"H1": "审核时间",
		"I1": "备注",
		"J1": "失败原因",
	}
	if list != nil {
		for k, v := range *list {
			checkTime := ""
			if v.CheckTime.IsZero() == false {
				checkTime = v.CheckTime.Format("2006-01-02 15:04:05")
			}
			i := utils.IntToStr(k + 2)
			data["A"+i] = v.Alipay
			data["B"+i] = v.AlipayName
			data["C"+i] = v.Amount
			data["D"+i] = v.RealAmount
			data["E"+i] = v.Fee
			data["F"+i] = v.Status
			data["G"+i] = v.Time.Format("2006-01-02 15:04:05")
			data["H"+i] = checkTime
			data["I"+i] = v.Remark
			data["J"+i] = v.Reason
		}
	}
	file := utils.Output(c, name, data)
	filename := name + ".xlsx"
	r := map[string]string{
		"file":     file,
		"filename": filename,
	}
	e.OutSuc(c, r, nil)
	return
}
func WithdrawalInvoiceImg(c *gin.Context) {
	var args map[string]string
	if err := c.ShouldBindJSON(&args); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	masterWithdrawalFlowDb := db.MasterWithdrawalFlowDb{}
	masterWithdrawalFlowDb.Set()
	flow := masterWithdrawalFlowDb.MasterWithdrawalFlowById(args["id"])
	flow.Img = args["img"]
	update := masterWithdrawalFlowDb.MasterWithdrawalFlowInsertUpdate(flow)
	if update == false {
		e.OutErr(c, 400, e.NewErr(400, "上传失败"))
		return
	}
	e.OutSuc(c, "success", nil)
	return
}

func WithdrawalBindAlipay(c *gin.Context) {
	var args map[string]string
	if err := c.ShouldBindJSON(&args); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	if args["alipay"] == "" || args["alipay_name"] == "" {
		e.OutErr(c, 400, e.NewErr(400, "支付宝信息不能为空"))
		return
	}
	masterId, _ := c.Get("master_id")
	mid := utils.AnyToString(masterId)
	masterDb := db.MasterDb{}
	masterDb.Set()
	master := masterDb.GetMaster(mid)
	master.AlipayName = args["alipay_name"]
	master.Alipay = args["alipay"]
	update := masterDb.MasterUpdate(master)
	if update == false {
		e.OutErr(c, 400, e.NewErr(400, "修改失败"))
		return
	}
	e.OutSuc(c, "success", nil)
	return
}

func commArg(c *gin.Context) (map[string]string, string, error) {
	masterId, _ := c.Get("master_id")
	mid := utils.AnyToString(masterId)
	fmt.Println(mid)
	var args map[string]string
	if err := c.ShouldBindJSON(&args); err != nil {
		return args, mid, err
	}
	return args, mid, nil

}

func masterInfo(mid string) map[string]string {
	masterDb := db.MasterDb{}
	masterDb.Set()
	master := masterDb.GetMaster(mid)
	res := make(map[string]string)
	if master != nil {
		res["id"] = utils.IntToStr(master.Id)
		res["alipay"] = master.Alipay
		res["alipay_name"] = master.AlipayName
	}
	return res
}
func masterAmount(mid, types string) map[string]string {
	masterInfos := masterInfo(mid)
	res := map[string]string{
		"amount":                   "0.00",
		"last_month_settle_amount": "0.00",
	}
	if masterInfos["id"] == "" {
		return res
	}

	puid := AppUserListPuid(mid)
	hwOwnOpen := offical.MasterListCfgGetOneData(puid, "hw_own_open")

	masterAmountDb := db.MasterAmountDb{}
	masterAmountDb.Set()
	masterAmounts := masterAmountDb.GetMasterAmountByExtendUid(masterInfos["id"], "0", types)
	if masterAmounts == nil {
		return res
	}
	res["agent_amount"] = "0"
	res["is_show_official_amount"] = "1"
	res["puid"] = puid
	res["is_show_agent_amount"] = "0"
	if utils.StrToInt(puid) > 0 && hwOwnOpen == "1" {
		res["is_show_agent_amount"] = "1"

		agentMasterAmounts := masterAmountDb.GetMasterAmountByExtendUid(masterInfos["id"], puid, types)
		if agentMasterAmounts != nil {
			if agentMasterAmounts.Amount != "" {
				res["agent_amount"] = agentMasterAmounts.Amount
			}
			res["agent_list_id"] = utils.IntToStr(agentMasterAmounts.Id)
			masterAmounts.LastMonthAmount = utils.Float64ToStr(utils.StrToFloat64(masterAmounts.LastMonthAmount) + utils.StrToFloat64(agentMasterAmounts.LastMonthAmount))
		}
		if utils.StrToFloat64(masterAmounts.Amount) == 0 {
			res["is_show_official_amount"] = "0"
		}
	}
	res["amount"] = masterAmounts.Amount
	if res["amount"] == "" {
		res["amount"] = "0"
	}
	res["id"] = masterAmounts.Uid
	res["list_id"] = utils.IntToStr(masterAmounts.Id)
	res["alipay"] = masterInfos["alipay"]
	res["alipay_name"] = masterInfos["alipay_name"]
	res["last_month_settle_amount"] = masterAmounts.LastMonthAmount
	if res["last_month_settle_amount"] == "" {
		res["last_month_settle_amount"] = "0"
	}
	return res
}
func masterMonthAmount(mid string) map[string]string {
	playletSaleOrder := db.PlayletSaleOrderDb{}
	playletSaleOrder.Set()
	lastMonthSum := playletSaleOrder.PlayletVideoOrderSum(mid, "", "last_month")
	monthSum := playletSaleOrder.PlayletVideoOrderSum(mid, "", "current_month")
	monthSettleSum := playletSaleOrder.PlayletVideoOrderSum(mid, "订单结算", "current_month")
	lastMonthTimeRange := utils.GetTimeRange("last_month")
	currentMonthTimeRange := utils.GetTimeRange("current_month")

	hwSum, _ := db.ZhimengDb.NotIn("status", []string{"创建订单", "订单退款", "订单失效"}).Where("uid=? and create_time>=? and create_time<?", mid, lastMonthTimeRange["start"], lastMonthTimeRange["end"]).Sum(&model.HwOrder{}, "commission")
	guideSum, _ := db.ZhimengDb.NotIn("status", []string{"创建订单", "订单退款", "订单失效"}).Where("uid=? and create_time>=? and create_time<?", mid, lastMonthTimeRange["start"], lastMonthTimeRange["end"]).Sum(&model.GuideOrder{}, "commission")
	lastMonthSum += hwSum + guideSum

	hwMonthSum, _ := db.ZhimengDb.NotIn("status", []string{"创建订单", "订单退款", "订单失效"}).Where("uid=? and create_time>=? and create_time<?", mid, currentMonthTimeRange["start"], currentMonthTimeRange["end"]).Sum(&model.HwOrder{}, "commission")
	guideMonthSum, _ := db.ZhimengDb.NotIn("status", []string{"创建订单", "订单退款", "订单失效"}).Where("uid=? and create_time>=? and create_time<?", mid, currentMonthTimeRange["start"], currentMonthTimeRange["end"]).Sum(&model.GuideOrder{}, "commission")
	monthSum += hwMonthSum + guideMonthSum

	hwMonthSettleSum, _ := db.ZhimengDb.In("status", []string{"订单结算"}).Where("uid=? and create_time>=? and create_time<?", mid, currentMonthTimeRange["start"], currentMonthTimeRange["end"]).Sum(&model.HwOrder{}, "commission")
	guideMonthSettleSum, _ := db.ZhimengDb.In("status", []string{"订单结算"}).Where("uid=? and create_time>=? and create_time<?", mid, currentMonthTimeRange["start"], currentMonthTimeRange["end"]).Sum(&model.GuideOrder{}, "real_commission")
	monthSettleSum += hwMonthSettleSum + guideMonthSettleSum

	res := map[string]string{
		"last_month_amount":   utils.Float64ToStr(lastMonthSum),
		"month_amount":        utils.Float64ToStr(monthSum),
		"month_settle_amount": utils.Float64ToStr(monthSettleSum),
	}
	return res
}