package phpjx

import (
	"errors"
	"fmt"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"strings"
	"time"

	"git.rosy.net.cn/baseapi/platformapi/jdapi"
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/partner"
)

type Data4AfsOrderSku struct {
	VendorSkuID   string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` // 平台skuid
	PromotionType int    `json:"promotionType"`                                    // 商品级别促销类型 (1、无优惠;2、秒杀(已经下线);3、单品直降;4、限时抢购;1202、加价购;1203、满赠(标识商品);6、买赠(买A送B，标识B);9999、表示一个普通商品参与捆绑促销，设置的捆绑类型;9998、表示一个商品参与了捆绑促销，并且还参与了其他促销类型;9997、表示一个商品参与了捆绑促销，但是金额拆分不尽,9996:组合购,8001:轻松购会员价,8:第二件N折,9:拼团促销)
	Name          string `orm:"size(255)" json:"name"`                             // 商品名
	SalePrice     int64  `json:"salePrice"`                                        // 售卖价
	Count         int    `json:"count"`                                            // 订单下单数量
}

type Data4AfsOrder struct {
	VendorOrderID string    `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
	AfsOrderID    string    `orm:"column(afs_order_id);size(48)" json:"afsOrderID"`       // 售后订单ID
	AfsCreatedAt  time.Time `orm:"type(datetime);null;index" json:"afsCreatedAt"`         // 售后单生成时间
	VendorStoreID string    `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid

	VendorStatus     string `orm:"size(255)" json:"vendorStatus"`
	VendorReasonType string `orm:"size(255)" json:"vendorReasonType"` // 原始售后原因
	ReasonDesc       string `orm:"size(1024)" json:"reasonDesc"`      // 售后原因描述
	ReasonImgList    string `orm:"size(1024)" json:"reasonImgList"`   // 售后描述图片
	VendorAppealType string `orm:"size(255)" json:"vendorAppealType"` // 原始售后方式
	Skus             []*Data4AfsOrderSku
}

func OnAfsOrderMsg(msg *CallbackMsg) (err error) {
	//jxutils.CallMsgHandlerAsync(func() {
	err = onAfsOrderMsg(msg)
	//}, jxutils.ComposeUniversalOrderID(msg.ThingID, model.VendorIDJX))
	return err
}

func CheckOrderSkuCanRefund(db *dao.DaoDB, afsOrder *Data4AfsOrder) error {
	// 获取此订单商品吃否存在售后单
	refundFinancial, err := dao.GetOrderRefundSkuList(db, []string{afsOrder.VendorOrderID})
	if err != nil && !strings.Contains(err.Error(), "no row found") {
		return nil
	}

	if len(refundFinancial) == model.NO {
		return nil
	}

	for _, r := range refundFinancial {
		for _, s := range afsOrder.Skus {
			if r.SkuID == utils.Str2Int(s.VendorSkuID) {
				return fmt.Errorf("商品:[%s],已经存在售后单无法重复申请", s.Name)
			}
		}
	}

	// 获取用户下单商品列表
	skuList, err := dao.GetSimpleOrderSkus(dao.GetDB(), afsOrder.VendorOrderID, nil)
	if err != nil {
		return err
	}

	var really = make(map[int]bool, 0)
	for _, s := range skuList {
		really[s.SkuID] = true
	}
	for _, v := range afsOrder.Skus {
		if _, ok := really[utils.Str2Int(v.VendorSkuID)]; !ok {
			return fmt.Errorf("商品:[%s],不是购买商品", v.Name)
		}
	}

	return nil
}

func buildAfsOrder(msg *CallbackMsg) (outAfsOrder *model.AfsOrder, err error) {
	var afsOrder *Data4AfsOrder
	var db = dao.GetDB()
	if err = utils.UnmarshalUseNumber([]byte(msg.Data), &afsOrder); err == nil {
		if err := CheckOrderSkuCanRefund(db, afsOrder); err != nil {
			return nil, err
		}

		outAfsOrder = &model.AfsOrder{
			VendorID:      model.VendorIDJX,
			AfsOrderID:    afsOrder.AfsOrderID,
			VendorOrderID: afsOrder.VendorOrderID,
			VendorStoreID: afsOrder.VendorStoreID,
			StoreID:       int(utils.Str2Int64WithDefault(afsOrder.VendorStoreID, 0)),
			AfsCreatedAt:  afsOrder.AfsCreatedAt,

			VendorStatus:     afsOrder.VendorStatus,
			VendorReasonType: afsOrder.VendorReasonType,
			ReasonType:       int8(utils.Str2Int64WithDefault(afsOrder.VendorReasonType, 0)),
			ReasonDesc:       utils.LimitUTF8StringLen(afsOrder.ReasonDesc, 1024),
			ReasonImgList:    afsOrder.ReasonImgList,
			VendorAppealType: afsOrder.VendorAppealType,
			AppealType:       int8(utils.Str2Int64WithDefault(afsOrder.VendorAppealType, 0)),
			Flag:             model.OrderFlagMaskTempJX,
		}
		outAfsOrder.Status = int(utils.Str2Int64WithDefault(afsOrder.VendorStatus, 0))

		skuNumber := 0 // 申请退款商品种类个数
		skuCount := 0  // 申请商品退款总条数
		refundMoney := 0
		// 当前申请退款的商品
		for _, x := range afsOrder.Skus {
			orderSku := &model.OrderSkuFinancial{
				Count:       x.Count,
				VendorSkuID: x.VendorSkuID,
				SkuID:       int(utils.Str2Int64WithDefault(x.VendorSkuID, 0)),
				Name:        x.Name,
				UserMoney:   x.SalePrice * int64(x.Count),
			}
			if x.PromotionType != 0 && x.PromotionType != jdapi.PromotionTypeNormal {
				orderSku.StoreSubName = utils.Int2Str(x.PromotionType)
			}
			outAfsOrder.Skus = append(outAfsOrder.Skus, orderSku)
			skuCount += orderSku.Count
			skuNumber++
			refundMoney += x.Count * int(x.SalePrice)
		}
		// 已经退款商品
		refundFinancial, err := dao.GetStoreAfsOrderSkuList2(db, []string{afsOrder.VendorOrderID})
		if err != nil && !dao.IsNoRowsError(err) {
			return nil, err
		}
		for _, f := range refundFinancial {
			skuCount += f.Count
			skuNumber++
			refundMoney += f.Count * int(f.SalePrice)
		}

		// 获取订单商品列表(所有的订单商品)
		skuList, err := dao.GetSimpleOrderSkus(dao.GetDB(), afsOrder.VendorOrderID, nil)
		if err != nil {
			return nil, err
		}

		makeOrderSkuCount := 0
		afsOrderOrderSkuCount := 0
		refundFinacialSkuCount := 0
		for _, v := range skuList {
			makeOrderSkuCount += v.Count
		}
		for _, v := range afsOrder.Skus {
			afsOrderOrderSkuCount += v.Count
		}
		for _, v := range refundFinancial {
			refundFinacialSkuCount += v.Count
		}
		// 这么写主要是不想让满足条件一的进入条件三
		if makeOrderSkuCount == afsOrderOrderSkuCount && refundFinacialSkuCount == model.NO { // 整单退
		} else if makeOrderSkuCount-refundFinacialSkuCount == model.YES && makeOrderSkuCount == model.YES { // 整单退且只有一个商品
		} else if makeOrderSkuCount-refundFinacialSkuCount-afsOrderOrderSkuCount == model.NO && afsOrderOrderSkuCount > 0 { // 分单退最后一个,不给退
			return nil, errors.New("如需整单退款,请使用整单退,无法分批次整单退款")
		}

		orderSkuNumber := 0
		orderSkuCount := 0
		for _, v := range skuList {
			orderSkuNumber++
			orderSkuCount += v.Count
		}
		if skuNumber == orderSkuNumber && skuCount == orderSkuCount {
			outAfsOrder.RefundType = model.AfsTypeFullRefund
		} else { // 部分退款,只退还商品部分
			outAfsOrder.RefundType = model.AfsTypePartRefund
		}
	}
	return outAfsOrder, err
}

func callbackAfsMsg2Status(msg *CallbackMsg) *model.OrderStatus {
	orderStatus := &model.OrderStatus{
		VendorOrderID:    msg.ThingID2, // 是售后单ID，不是订单ID，订单ID在RefVendorOrderID中
		VendorID:         model.VendorIDJX,
		OrderType:        model.OrderTypeAfsOrder,
		RefVendorOrderID: msg.ThingID,
		RefVendorID:      model.VendorIDJX,
		VendorStatus:     msg.SubMsgType,
		Status:           int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)),
		StatusTime:       time.Now(),
		Remark:           "",
	}
	return orderStatus
}

func onAfsOrderMsg(msg *CallbackMsg) (err error) {
	subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0))
	status := callbackAfsMsg2Status(msg)
	if subMsgType == model.AfsOrderStatusWait4Approve || subMsgType == model.AfsOrderStatusNew {
		afsOrder, err2 := buildAfsOrder(msg)
		if err = err2; err == nil {
			err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status)
		}
	} else {
		err = partner.CurOrderManager.OnOrderStatusChanged("", status)
	}
	return err
}

func postFakeAfsMsg(orderNo, afsOrderID string, status int) {
	msg := &CallbackMsg{
		AppKey:     appKey,
		MsgType:    MsgTypeAfsOrder,
		SubMsgType: utils.Int2Str(status),
		ThingID:    orderNo,
		ThingID2:   afsOrderID,
		Timestamp:  time.Now().Unix(),
	}
	utils.CallFuncAsync(func() {
		OnCallbackMsg(msg)
	})
}

func NotifyAfsOrderStatusChanged(order *model.AfsOrder, status int) (err error) {
	orderMsg := *order
	orderMsg.Status = status
	if err = jxAPI.NotifyAfsOrderStatusChanged(&orderMsg); err == nil {
		postFakeAfsMsg(orderMsg.VendorOrderID, orderMsg.AfsOrderID, orderMsg.Status)
	}
	return err
}
