package controllers

import (
	"encoding/json"
	"fmt"
	"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
	"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/business/partner"
	"git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api"
	"github.com/astaxie/beego/server/web"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"time"
)

type MtwmController struct {
	web.Controller
}

var MTWMVendorStoreIDMap = new(sync.Map)

func (c *MtwmController) onCallbackMsg(msgType string) {
	msg, callbackResponse := api.MtwmAPI.GetCallbackMsg(c.Ctx.Request)
	if callbackResponse == nil {
		vendorStoreId := msg.FormData.Get("app_poi_code")
		if vendorStoreId == "" {
			vendorStoreId = msg.FormData.Get("wm_poi_id")
		}
		if msgType == mtwmapi.MsgTypeOrderFinishedPickup && vendorStoreId == "" {
			finishedPickup := FinishedPickup{}
			json.Unmarshal([]byte(msg.FormData.Get("pick_up_data")), &finishedPickup)
			vendorStoreId = finishedPickup.AppPoiCode
		}

		if _, have := MTWMVendorStoreIDMap.Load(vendorStoreId); vendorStoreId != "" && !have {
			storeDetail, _ := dao.GetStoreDetailByVendorStoreID(dao.GetDB(), vendorStoreId, model.VendorIDMTWM, "")
			if storeDetail == nil {
				switch web.BConfig.RunMode {
				case model.ServerTypeVegetable, "dev":
					callbackResponse = pushMTWMOrder2GY(msg.FormData, msgType, model.ServerTypeFruits)
				case model.ServerTypeFruits:
					callbackResponse = pushMTWMOrder2GY(msg.FormData, msgType, model.ServerTypePet)
				case model.ServerTypePet:
					callbackResponse = mtwmapi.Err2CallbackResponse(nil, "") // mtwmapi.Err2CallbackResponse(fmt.Errorf("美团菜市推果园,果园退超市未找到门店cmd:%s,storeId:%s", msgType, vendorStoreId), "")
				}

				c.Data["json"] = mtwmapi.Err2CallbackResponse(nil, "")
				c.ServeJSON()
				return
			} else {
				MTWMVendorStoreIDMap.Store(vendorStoreId, model.YES)
			}
		}

		callbackResponse = mtwm.OnCallbackMsg(msg, msgType)
		if callbackResponse == nil {
			callbackResponse = mtwmapi.Err2CallbackResponse(nil, "")
		}
	}

	c.Data["json"] = callbackResponse
	c.ServeJSON()
}

func (c *MtwmController) WaybillStatus() {
	c.onCallbackMsg(mtwmapi.MsgTypeWaybillStatus)
}

func (c *MtwmController) NewOrder() {
	c.onCallbackMsg(mtwmapi.MsgTypeNewOrder)
}

func (c *MtwmController) OrderAccepted() {
	time.Sleep(500 * time.Millisecond) // 测试看看有的订单来不拣货,可能是这个状态推的太快了,上一个NewOrder还没处理结束导致的
	c.onCallbackMsg(mtwmapi.MsgTypeOrderAccepted)
}

func (c *MtwmController) OrderFinished() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderFinished)
}

func (c *MtwmController) OrderFinancial() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderFinancial)
}

func (c *MtwmController) UserUrgeOrder() {
	c.onCallbackMsg(mtwmapi.MsgTypeUserUrgeOrder)
}

func (c *MtwmController) NumberDowngrade() {
	c.onCallbackMsg(mtwmapi.MsgTypePrivateNumberDowngrade)
}

func (c *MtwmController) OrderModified() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderModified)
}

func (c *MtwmController) OrderCanceled() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderCanceled)
}

func (c *MtwmController) OrderRefund() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderRefund)
}

func (c *MtwmController) OrderPartialRefund() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderPartialRefund)
}

func (c *MtwmController) StoreStatusChanged() {
	c.onCallbackMsg(mtwmapi.MsgTypeStoreStatusChanged)
}

func (c *MtwmController) OrderFinishedPickup() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderFinishedPickup)
}

func (c *MtwmController) StoreAuditStatusChanged() {
	c.onCallbackMsg(mtwmapi.MsgTypeStoreAuditStatusChanged)
}

func (c *MtwmController) SkuDelete() {
	c.onCallbackMsg(mtwmapi.MsgTypeSkuDelete)
}

func (c *MtwmController) SkuUpdate() {
	c.onCallbackMsg(mtwmapi.MsgTypeSkuUpdate)

}

func (c *MtwmController) StoreBind() {
	c.onCallbackMsg(mtwmapi.MsgTypeStoreBind)
}

func (c *MtwmController) IMCallback() {
	c.OnIMCallback()
}

func (c *MtwmController) DeliveryFeeChange() {
	c.onCallbackMsg(mtwmapi.MsgTypeOrderDeliveryFeeChange)
}

// Invoice 发票推送
func (c *MtwmController) Invoice() {
	msg, callbackResponse := api.MtwmAPI.GetCallbackMsg(c.Ctx.Request)
	if callbackResponse != nil {
		c.Data["json"] = map[string]interface{}{"result_code": -1}
		c.ServeJSON()
		return
	}

	data := &mtwmapi.InvoiceCallback{}
	utils.Map2StructByJson(utils.URLValues2Map(msg.FormData), data, false)
	// 消息通知
	if err := mtwm.InvoiceCallback(data); err != nil {
		globals.SugarLogger.Errorf("mtwm Invoice err := %v", err)
	}
	c.Data["json"] = map[string]interface{}{"result_code": 1}
	c.ServeJSON()

}

func (c *MtwmController) OnIMCallback() {
	c.Data["json"] = mtwmapi.Err2CallbackResponse(nil, "")
	msg, callbackResponse := api.MtwmAPI.GetIMCallbackMsg(c.Ctx.Request)
	if callbackResponse == nil {
		callbackResponse = mtwm.OnImMsg(msg)
		if callbackResponse == nil {
			callbackResponse = mtwmapi.Err2CallbackResponse(nil, "")
		}
	}
	c.Data["json"] = callbackResponse
	c.ServeJSON()
}

type FinishedPickup struct {
	AppPoiCode    string `json:"app_poi_code"`
	ConsumingTime int    `json:"consuming_time"`
	OrderId       int64  `json:"order_id"`
	OrderViewId   int64  `json:"order_view_id"`
	PickTime      string `json:"pick_time"`
	PickType      string `json:"pick_type"`
}

// 订单所属门店在菜市不存在时尝试推送到果园去
func pushMTWMOrder2GY(value url.Values, msgType string, serverType string) *mtwmapi.CallbackResponse {
	cl := http.Client{}
	var request *http.Request
	var err error

	switch serverType {
	case model.ServerTypeFruits:
		request, err = http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/mtwm/"+msgType, strings.NewReader(value.Encode()))
	case model.ServerTypePet:
		request, err = http.NewRequest(http.MethodPost, "http://callback-gblm.jxc4.com/mtwm/"+msgType, strings.NewReader(value.Encode()))
	}
	if err != nil {
		return mtwmapi.Err2CallbackResponse(err, "")
	}
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("accept", "application/json, text/plain, */*")
	resp, err := cl.Do(request)
	if err != nil {
		return mtwmapi.Err2CallbackResponse(err, "")
	}
	defer resp.Body.Close()
	byteData, _ := ioutil.ReadAll(resp.Body)

	result := mtwmapi.CallbackResponse{}
	json.Unmarshal(byteData, &result)

	return &result
}

// ImgCheckOutCallback 针对返图订单，当实拍审核失败时，通过该消息通知三方重新修改实拍
// http://callback.jxc4.com//mtwm/imgCheckOutCallback
func (c *MtwmController) ImgCheckOutCallback() {
	msg, callbackResponse := api.MtwmAPI.GetCallbackMsg(c.Ctx.Request)
	if callbackResponse != nil {
		c.Data["json"] = map[string]interface{}{"result_code": -1}
		c.ServeJSON()
		return
	}

	data := &CheckBackParam{}
	if err := utils.Map2StructByJson(utils.URLValues2Map(msg.FormData), data, false); err != nil {
		c.Data["json"] = map[string]interface{}{"result_code": -1}
		c.ServeJSON()
		return
	}

	if data.AuditStatus == 0 {
		c.Data["json"] = map[string]interface{}{"result_code": 1}
		c.ServeJSON()
		return
	}

	order, err := partner.CurOrderManager.LoadOrder(data.OrderViewId, model.VendorIDMTWM)
	if err != nil {
		c.Data["json"] = map[string]interface{}{"result_code": -1}
		c.ServeJSON()
		return
	}
	if data.AuditStatus == 2 { // 审核失败
		order.ForceRequirePicture = 2
		riskDesc := ""
		for _, v := range data.RiskInfoList {
			riskDesc += v.RiskDesc + ","
		}
		partner.CurOrderManager.OnOrderMsg(order, utils.Int2Str(data.AuditStatus), riskDesc)
	} else if data.AuditStatus == 3 { // 审核成功
		order.ForceRequirePicture = 3
	}
	dao.UpdateEntity(dao.GetDB(), order, "ForceRequirePicture")

	ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "ImgCheckOutCallback", fmt.Sprintf("美团返图审核:%s", utils.Format4Output(data, false)))
	globals.SugarLogger.Debugf("-----data := %s", utils.Format4Output(data, false))
	c.Data["json"] = map[string]interface{}{"result_code": 1}
	c.ServeJSON()

}

type CheckBackParam struct {
	OrderViewId  string `json:"order_view_id"` // 订单号，商家可根据订单号查询订单当前的详细信息。
	AuditStatus  int    `json:"audit_status"`  // 审核状态，2:审核失败 ，3:审核通过
	RiskInfoList []struct {
		RiskInfo int    `json:"risk_info"` // 1.含违规信息 2.重复上传 3.图片模糊
		RiskDesc string `json:"risk_desc"` // 含违规信息
		Url      string `json:"url"`       // 审核失败的图片url，注意：为美团侧转换后的url
	} `json:"risk_info_list"`
}

// OrderImgStatusCallback 针对强制返图订单，当订单返图就绪满足发配条件时，通过该消息通知三方是否可发配
// http://callback.jxc4.com//mtwm/orderImgStatusCallback
func (c *MtwmController) OrderImgStatusCallback() {
	msg, callbackResponse := api.MtwmAPI.GetCallbackMsg(c.Ctx.Request)
	if callbackResponse != nil {
		c.Data["json"] = map[string]interface{}{"result_code": -1}
		c.ServeJSON()
		return
	}

	data := &CanSendDelivery{}
	if err := utils.Map2StructByJson(utils.URLValues2Map(msg.FormData), data, false); err != nil {
		c.Data["json"] = map[string]interface{}{"result_code": -1}
		c.ServeJSON()
		return
	}

	order, err := partner.CurOrderManager.LoadOrder(data.OrderViewId, model.VendorIDMTWM)
	if err != nil {
		c.Data["json"] = map[string]interface{}{"result_code": -1}
		c.ServeJSON()
		return
	}

	if data.EnableDispatch {
		order.ForceRequirePicture = 3
	} else {
		order.ForceRequirePicture = 2
	}
	dao.UpdateEntity(dao.GetDB(), order, "ForceRequirePicture")

	ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "OrderImgStatusCallback", fmt.Sprintf("美团返图审核可发配:%s", utils.Format4Output(data, false)))
	globals.SugarLogger.Debugf("-----data := %s", utils.Format4Output(data, false))

	c.Data["json"] = map[string]interface{}{"result_code": 1}
	c.ServeJSON()
}

type CanSendDelivery struct {
	OrderViewId             string `json:"order_view_id"`   // 订单号，商家可根据订单号查询订单当前的详细信息。
	SendTime                string `json:"send_time"`       // 消息发送时间，秒级时间戳
	EnableDispatch          bool   `json:"enable_dispatch"` // true-可发配 false-不可发配
	DispatchConditionDetail []struct {
		ConditionType  int  `json:"condition_type"`  // 发配条件限制类型 ：1-强制返图
		EnableDispatch bool `json:"enable_dispatch"` // 某个发配条件限制类型是否已经满足
	} // 发货条件明细

}
