package controllers

import (
	"encoding/json"
	"fmt"
	"git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
	"git.rosy.net.cn/baseapi/utils"
	"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/purchase/tiktok_store"
	"github.com/astaxie/beego/server/web"
	"io/ioutil"
	"net/http"
	"time"
)

type LogisticsController struct {
	web.Controller
}

//#region  美团物流注册(发货完成时注册)

// LogisticsRegisterReq 注册接口请求参数
type LogisticsRegisterReq struct {
	TrackNo     string `json:"track_no"`     // 运单号
	CallbackUrl string `json:"callback_url"` // 回调地址
	Company     string `json:"company"`      //物流公司编码
}

// LogisticsRegisterResp 响应接口
type LogisticsRegisterResp struct {
	Result     bool   `json:"result"`
	ReturnCode string `json:"return_code"`
	Message    string `json:"message"`
}

// LogisticsRegister 即时配轨迹订阅接口
func (c *LogisticsController) LogisticsRegister() {
	body, _ := ioutil.ReadAll(c.Ctx.Request.Body)

	register := &LogisticsRegisterReq{}
	if err := json.Unmarshal(body, register); err != nil {
		c.Data["json"] = LogisticsRegisterResp{
			Result:     false,
			ReturnCode: "1007",
			Message:    err.Error(),
		}
		c.ServeJSON()
		return
	}
	if register.TrackNo == "" {
		c.Data["json"] = LogisticsRegisterResp{
			Result:     false,
			ReturnCode: "1002",
			Message:    "单号不存在",
		}
		c.ServeJSON()
		return
	}
	// 查询订单的运单是否存在
	data, _ := dao.GetWayBillsByWayBillId(dao.GetDB(), register.TrackNo)

	// 此订单可能是果园订单
	if len(data) == 0 {
		var resp *http.Response
		var err error
		switch web.BConfig.RunMode {
		case model.ServerTypeVegetable:
			//resp, err = tiktok_store.HttpToGuoYuan(utils.Struct2Map(register, "", true), tiktok_store.CaiShiPushGyTagDeliveryRegister, model.ServerTypeFruits)
			//if err != nil {
			//	c.Data["json"] = LogisticsQueryRestMsg("单号不存在", "1002")
			//	c.ServeJSON()
			//	return
			//}

			// 抖音只推送百货
			resp, err = tiktok_store.HttpToGuoYuan(utils.Struct2Map(register, "", true), tiktok_store.CaiShiPushGyTagDeliveryRegister, model.ServerTypePet)
			if err != nil {
				c.Data["json"] = LogisticsQueryRestMsg("单号不存在", "1002")
				c.ServeJSON()
				return
			}
		case model.ServerTypeFruits:
			//resp, err = tiktok_store.HttpToGuoYuan(utils.Struct2Map(register, "", true), tiktok_store.CaiShiPushGyTagDeliveryRegister, model.ServerTypePet)
			//if err != nil {
			//	c.Data["json"] = LogisticsQueryRestMsg("单号不存在", "1002")
			//	c.ServeJSON()
			//	return
			//}
		}

		gyData := &LogisticsRegisterResp{}
		gyBody, _ := ioutil.ReadAll(resp.Body)
		if err := json.Unmarshal(gyBody, gyData); err != nil {
			c.Data["json"] = LogisticsQueryRestMsg("单号不存在", "1002")
			c.ServeJSON()
			return
		}
		c.Data["json"] = gyData
		c.ServeJSON()
	}

	c.Data["json"] = LogisticsRegisterResp{
		Result:     true,
		ReturnCode: "200",
		Message:    "",
	}
	c.ServeJSON()
	return
}

//#endregion

//#region 保底物流信息更新

// LogisticsQueryReq 请求参数
type LogisticsQueryReq struct {
	TrackNo       string `json:"track_no"`        // 运单号
	Company       string `json:"company"`         // 物流商编码
	PhoneLastFour string `json:"phone_last_four"` // 手机号后4位
}

// LogisticsQueryRest 响应参数
type LogisticsQueryRest struct {
	Result     bool               `json:"result"`      // 结果
	ReturnCode string             `json:"return_code"` // 错误码
	Message    string             `json:"message"`     // 错误消息
	Data       LogisticsQueryData `json:"data"`        // 轨迹数据
}

type LogisticsQueryData struct {
	Timestamp string       `json:"timestamp"` // 运单状态时间
	TrackNo   string       `json:"track_no"`  // 运单号
	Traces    []TracesList `json:"traces"`    // 轨迹列表
}

type TracesList struct {
	Timestamp string `json:"timestamp"` // 当前系统时间
	// 事件编码
	Opcode string `json:"opcode"`
	// 文案
	Content string `json:"content"`
	// 骑手信息
	Rider RiderInfo `json:"rider"`
	// 三方运力公司，顺丰同城 sftc 闪送 shansong 达达 dada UU uupt 美团 meituan 蜂鸟 fengniao
	ThirdPartyCompany string `json:"third_party_company"`
	// 异常编码
	ExceptionCode string `json:"exception_code"`
	// 异常原因
	ExceptionDesc string `json:"exception_desc"`
	// 取消编码
	CancelCode string `json:"cancel_code"`
	// 取消原因
	CancelDesc string `json:"cancel_desc"`
}
type RiderInfo struct {
	Name   string `json:"name"`   // 	骑手姓名
	Mobile string `json:"mobile"` // 	骑手电话号码
}

// LogisticsQuery 即时配保底查询接口
func (c *LogisticsController) LogisticsQuery() {
	body, _ := ioutil.ReadAll(c.Ctx.Request.Body)
	param := &LogisticsQueryReq{}
	if err := json.Unmarshal(body, param); err != nil {
		c.Data["json"] = LogisticsQueryRestMsg("数据解析错误", "1005")
		c.ServeJSON()
		return
	}

	if param.TrackNo == "" {
		c.Data["json"] = LogisticsQueryRestMsg("运单账号不存在", "1002")
		c.ServeJSON()
		return
	}

	// 查询订单的运单是否存在
	data, err := dao.GetWayBillsByWayBillId(dao.GetDB(), param.TrackNo)
	if err != nil || len(data) == 0 {
		var resp *http.Response
		var err error
		switch web.BConfig.RunMode {
		case model.ServerTypeVegetable:
			//resp, err = tiktok_store.HttpToGuoYuan(utils.Struct2Map(param, "", true), tiktok_store.CaiShiPushGyTagDeliveryDetail, model.ServerTypeFruits)
			//if err != nil {
			//	c.Data["json"] = LogisticsQueryRestMsg("运单账号不存在", "1002")
			//	c.ServeJSON()
			//	return
			//}
			// 抖音只推送百货
			resp, err = tiktok_store.HttpToGuoYuan(utils.Struct2Map(param, "", true), tiktok_store.CaiShiPushGyTagDeliveryDetail, model.ServerTypePet)
			if err != nil {
				c.Data["json"] = LogisticsQueryRestMsg("运单账号不存在", "1002")
				c.ServeJSON()
				return
			}
		case model.ServerTypeFruits:
			resp, err = tiktok_store.HttpToGuoYuan(utils.Struct2Map(param, "", true), tiktok_store.CaiShiPushGyTagDeliveryDetail, model.ServerTypePet)
			if err != nil {
				c.Data["json"] = LogisticsQueryRestMsg("运单账号不存在", "1002")
				c.ServeJSON()
				return
			}
		case "jxpet":
			c.Data["json"] = LogisticsQueryRestMsg("运单账号不存在", "1002")
			c.ServeJSON()
			return
		}

		wayBillDetail := &LogisticsQueryRest{}
		gyBody, _ := ioutil.ReadAll(resp.Body)
		if err := json.Unmarshal(gyBody, wayBillDetail); err != nil {
			c.Data["json"] = LogisticsQueryRestMsg("json unmarshal", "1002")
			c.ServeJSON()
			return
		}
		c.Data["json"] = wayBillDetail
		c.ServeJSON()
		return
	}

	returnParam := &LogisticsQueryRest{
		Result:     true,
		ReturnCode: "200",
		Message:    "正常",
		Data: LogisticsQueryData{
			Timestamp: utils.Time2Str(data[0].StatusTime),
			TrackNo:   param.TrackNo,
			Traces: []TracesList{{
				Timestamp:         utils.Time2Str(time.Now()),
				Content:           "",
				ThirdPartyCompany: tiktok_api.TiktokExpressCode,
				ExceptionCode:     "",
				ExceptionDesc:     "",
				CancelCode:        "",
				CancelDesc:        "",
				Rider:             RiderInfo{Name: data[0].CourierName, Mobile: data[0].CourierMobile},
			}},
		},
	}

	switch data[0].Status {
	case 5: // 呼叫骑手
		returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsStatusCALLRIDER
		returnParam.Data.Traces[0].Content = "呼叫骑手,新建运单"
	case 10, 12: // 骑手接单
		returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsORDERRECEIVED
		returnParam.Data.Traces[0].Content = model.RiderWaitGetGoods
	case 15: // 到店
		returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsRIDERARRIVED
		returnParam.Data.Traces[0].Content = model.RiderToStore
	case 20: //配送中
		returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsRIDERPICKUP
		returnParam.Data.Traces[0].Content = model.RiderGetOrderDelivering
	case 105, 120: // 完成
		returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsDELIVERED
		returnParam.Data.Traces[0].Content = model.RiderGetOrderDelivered
	case 8, 115: // 取消
		returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsCANCELDELIVERY
		returnParam.Data.Traces[0].CancelCode = "3000" // 骑手原因取消
		returnParam.Data.Traces[0].CancelDesc = "繁忙"   // 骑手原因取消
		returnParam.Data.Traces[0].Content = "取消"
	case 22: //配送异常
		returnParam.Data.Traces[0].Opcode = tiktok_api.TiktokLogisticsINDDELIVERYEXCEPTION
		returnParam.Data.Traces[0].ExceptionCode = "5001"    // 服务商系统异常
		returnParam.Data.Traces[0].ExceptionDesc = "服务商系统异常" // 服务商系统异常
		returnParam.Data.Traces[0].Content = "异常订单/配送"
	}

	if returnParam.Data.Traces[0].Rider.Name == "" {
		returnParam.Data.Traces[0].Rider.Name = " 暂无骑手 "
	}
	if returnParam.Data.Traces[0].Rider.Mobile == "" {
		returnParam.Data.Traces[0].Rider.Mobile = " 暂无电话 "
	}

	switch data[0].Status {
	case 5, 10, 12, 15, 20, 105, 120:
		returnParam.Data.Traces[0].Content = fmt.Sprintf(returnParam.Data.Traces[0].Content, returnParam.Data.Traces[0].Rider.Name, returnParam.Data.Traces[0].Rider.Mobile)
	}

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

func LogisticsQueryRestMsg(err string, errCode string) LogisticsQueryRest {
	if err == "" {
		return LogisticsQueryRest{
			Result:     false,
			ReturnCode: errCode,
			Message:    err,
		}
	}
	return LogisticsQueryRest{
		Result:     false,
		ReturnCode: "1002",
		Message:    "json unmarshal",
	}
}

//#endregion
