package controllers

import (
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/auth2/authprovider/dingding"
	"git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
	"git.rosy.net.cn/jx-callback/business/jxstore/cms"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/jxutils/configindb"
	"git.rosy.net.cn/jx-callback/business/jxutils/datares"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/business/msghub"
	"git.rosy.net.cn/jx-callback/globals/api"
	"git.rosy.net.cn/jx-callback/globals/api/apimanager"
	"github.com/astaxie/beego/server/web"
)

type CmsController struct {
	web.Controller
}

// @Title 得到地点（省，城市，区）信息
// @Description 得到地点（省，城市，区）信息。
// @Param	token			header		string	false	"认证token"
// @Param	keyword			query		string	false	"查询关键字（可以为空，为空表示不限制）"
// @Param	parentCode		query		int		false	"上级地点code，这个指的是国家标准CODE（中国为：100000，北京为：110000，北京市为：110100），不是数据库中的ID"
// @Param	level			query		int		false	"地点级别：省为1，市为2，区为3，注意直辖市也要分省与市级"
// @Param	includeDisabled	query		bool	false	"是否包括禁用的城市（缺省不包括）"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetPlaces [get]
func (c *CmsController) GetPlaces() {
	c.callGetPlaces(func(params *tCmsGetPlacesParams) (retVal interface{}, errCode string, err error) {
		retVal, err = cms.GetPlaces(params.Ctx, params.Keyword, params.IncludeDisabled, params.MapData)
		return retVal, "", err
	})
}

// @Title 批量修改地点信息
// @Description 只支持修改enabled, jd_code和mtps_price这三个属性
// @Param	token			header		string	true	"认证token"
// @Param	payload			formData	string	true	"json数据，place对象数组"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /UpdatePlaces [put]
func (c *CmsController) UpdatePlaces() {
	c.callUpdatePlaces(func(params *tCmsUpdatePlacesParams) (retVal interface{}, errCode string, err error) {
		placeList := make([]map[string]interface{}, 0)
		if err = utils.UnmarshalUseNumber([]byte(params.Payload), &placeList); err == nil {
			retVal, err = cms.UpdatePlaces(params.Ctx, placeList, params.Ctx.GetUserName())
		}
		return retVal, "", err
	})
}

// @Title 修改地点信息
// @Description 只支持修改enabled, jd_code和mtps_price这三个属性
// @Param	token			header		string	true	"认证token"
// @Param	code			formData	int		true	"地点编号，注意是code不是ID"
// @Param	enabled			formData	bool	true	"是否启用"
// @Param	name			formData	string	false	"地点名"
// @Param	mtpsPrice		formData	int		false	"美团配送基础价格"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /UpdatePlace [put]
func (c *CmsController) UpdatePlace() {
	c.callUpdatePlace(func(params *tCmsUpdatePlaceParams) (retVal interface{}, errCode string, err error) {
		payload := map[string]interface{}{
			"code":    params.Code,
			"enabled": params.Enabled,
		}
		if params.Name != "" {
			payload["name"] = params.Name
		}
		if params.MtpsPrice > 0 {
			payload["mtpsPrice"] = params.MtpsPrice
		}
		retVal, err = cms.UpdatePlaces(params.Ctx, []map[string]interface{}{payload}, params.Ctx.GetUserName())
		return retVal, "", err
	})
}

// @Title 得到服务相关的一些基础信息
// @Description 得到服务相关的一些基础信息，包括版本，及一些元数据信息
// @Param	token			header		string	true	"认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetServiceInfo [get]
func (c *CmsController) GetServiceInfo() {
	c.callGetServiceInfo(func(params *tCmsGetServiceInfoParams) (retVal interface{}, errCode string, err error) {
		retVal = cms.GetServiceInfo(params.Ctx)
		return retVal, "", err
	})
}

// @Title 得到七牛上传服务临时token
// @Description 得到七牛上传服务临时token，当前设置为5分钟内有效。正常使用场景为每次上传资源前实时获取，而不是保存下来一直使用，如果hashCode有值，且本地有，可能直接返回URL
// @Param	token			header		string	true	"认证token"
// @Param	suffix			query		string	true	"前缀"
// @Param	hashCode		query		string	false	"图片hash"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetQiniuUploadToken [get]
func (c *CmsController) GetQiniuUploadToken() {
	c.callGetQiniuUploadToken(func(params *tCmsGetQiniuUploadTokenParams) (retVal interface{}, errCode string, err error) {
		retVal, err = datares.GetQiniuUploadToken(params.Ctx, params.Suffix, params.HashCode)
		return retVal, "", err
	})
}

// 此函数可以不用调用，当前只有菜谱图片在调用
// @Title 注册数据资源
// @Description 注册数据资源
// @Param	token			header		string	true	"认证token"
// @Param	hashCode		formData	string	true	"md5"
// @Param	resourceURL		formData	string	true	"资源URL"
// @Param	mimeType		formData	string	true	"资源MIME类型，当前只支持:image/jpeg,image/png,video/mpeg,video/mp4"
// @Param	name			formData	string	faslse	"资源名"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /RegisterDataResource [post]
func (c *CmsController) RegisterDataResource() {
	c.callRegisterDataResource(func(params *tCmsRegisterDataResourceParams) (retVal interface{}, errCode string, err error) {
		// retVal, err = datares.RegisterDataResource(params.Ctx, params.Name, params.ResourceURL, params.MimeType, params.HashCode, nil, model.ImgTypeLocal, true)
		return retVal, "", err
	})
}

// @Title 根据坐标得到区码
// @Description 根据坐标得到区码，坐标都为火星坐标（有些市是没有区的，比如东莞，这种情况下返回的区码是一个假的区域，即市的编码加上9000000）
// @Param	token			header		string	true	"认证token"
// @Param	lng				query		number	true	"经度"
// @Param	lat				query		number	true	"纬度"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetCoordinateDistrictCode [get]
func (c *CmsController) GetCoordinateDistrictCode() {
	c.callGetCoordinateDistrictCode(func(params *tCmsGetCoordinateDistrictCodeParams) (retVal interface{}, errCode string, err error) {
		retVal, err = cms.GetCoordinateDistrictCode(params.Ctx, params.Lng, params.Lat)
		return retVal, "", err
	})
}

// @Title 根据坐标得到城市
// @Description 根据坐标得到城市
// @Param	token			header		string	true	"认证token"
// @Param	lng				query		number	true	"经度"
// @Param	lat				query		number	true	"纬度"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetCoordinateCityInfo [get]
func (c *CmsController) GetCoordinateCityInfo() {
	c.callGetCoordinateCityInfo(func(params *tCmsGetCoordinateCityInfoParams) (retVal interface{}, errCode string, err error) {
		retVal, err = cms.GetCoordinateCityInfo(params.Ctx, params.Lng, params.Lat)
		return retVal, "", err
	})
}

// @Title 得到配置参数
// @Description 得到配置参数
// @Param	token			header		string	true	"认证token"
// @Param	key				query		string	true	"参数名"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetConfig [get]
func (c *CmsController) GetConfig() {
	c.callGetConfig(func(params *tCmsGetConfigParams) (retVal interface{}, errCode string, err error) {
		retVal, err = configindb.GetConfig(params.Key, "")
		return retVal, "", err
	})
}

// @Title 设置配置参数
// @Description 设置配置参数
// @Param	token			header		string	true	"认证token"
// @Param	key				query		string	true	"参数名"
// @Param	value			query		string	true	"参数值"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SetConfig [put]
func (c *CmsController) SetConfig() {
	c.callSetConfig(func(params *tCmsSetConfigParams) (retVal interface{}, errCode string, err error) {
		retVal, err = configindb.SetConfig(params.Ctx, params.Key, params.Value)
		return retVal, "", err
	})
}

// @Title 从条形码得到商品信息
// @Description 从条形码得到商品信息
// @Param	token			header		string	true	"认证token"
// @Param	barCode			query		string	true	"条形码"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetProductInfoByBarCode [get]
func (c *CmsController) GetProductInfoByBarCode() {
	c.callGetProductInfoByBarCode(func(params *tCmsGetProductInfoByBarCodeParams) (retVal interface{}, errCode string, err error) {
		retVal, err = api.ShowAPI.GetProductInfoByBarCode(params.BarCode)
		return retVal, "", err
	})
}

// @Title 得到服务器消息通知
// @Description 得到服务器消息通知
// @Param	token			header		string	true	"认证token"
// @Param	storeID			query		int		true	"京西门店ID"
// @Param	lastOrderTime	query		string	false	"最后订单时间（缺省为24小时内）"
// @Param	lastOrderSeqID	query		string	false	"最后订单流水ID（缺省为0）"
// @Param	waitingSecond	query		int		false	"等待时间"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetNewOrderMsg [get]
func (c *CmsController) GetNewOrderMsg() {
	c.callGetNewOrderMsg(func(params *tCmsGetNewOrderMsgParams) (retVal interface{}, errCode string, err error) {
		timeList, err := jxutils.BatchStr2Time(params.LastOrderTime)
		if err == nil {
			lastOrderSeqID := utils.Str2Int64WithDefault(params.LastOrderSeqID, 0)
			retVal, err = msghub.GetMsg(params.Ctx, params.StoreID, timeList[0], lastOrderSeqID, nil, params.WaitingSecond)
		}
		return retVal, "", err
	})
}

// @Title 发送新订单消息（测试用）
// @Description 发送新订单消息（测试用）
// @Param	token			header		string	true	"认证token"
// @Param	vendorOrderID	formData	string	true	"订单ID"
// @Param	vendorID		formData	int		true	"订单厂商ID"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /FakeNewOrder [post]
func (c *CmsController) FakeNewOrder() {
	c.callFakeNewOrder(func(params *tCmsFakeNewOrderParams) (retVal interface{}, errCode string, err error) {
		order, err := orderman.FixedOrderManager.LoadOrder(params.VendorOrderID, params.VendorID)
		if err == nil {
			msghub.OnNewOrder(order)
		}
		return retVal, "", err
	})
}

// @Title 发送消息给相关人员
// @Description 发送消息给相关人员
// @Param	msgType			formData	string	true	"消息类型"
// @Param	msgContent		formData	string	true	"消息内容"
// @Param	mobile			formData	string	false	"手机号"
// @Param	verifyCode		formData	string	false	"验证码"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SendMsg2Somebody [post]
func (c *CmsController) SendMsg2Somebody() {
	c.callSendMsg2Somebody(func(params *tCmsSendMsg2SomebodyParams) (retVal interface{}, errCode string, err error) {
		err = cms.SendMsg2Somebody(params.Ctx, params.Mobile, params.VerifyCode, params.MsgType, params.MsgContent)
		return retVal, "", err
	})
}

// @Title 新增配置
// @Description 新增配置
// @Param	token			header		string	true	"认证token"
// @Param	type			formData	string	true	"配置类型（当前只支持PricePack）"
// @Param	key				formData	string	true	"配置名"
// @Param	value			formData	string	true	"配置值"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /NewConfig [post]
func (c *CmsController) NewConfig() {
	c.callNewConfig(func(params *tCmsNewConfigParams) (retVal interface{}, errCode string, err error) {
		err = cms.AddConfig(params.Ctx, params.Key, params.Type, params.Value)
		return retVal, "", err
	})
}

// @Title 删除配置
// @Description 删除配置
// @Param	token			header		string	true	"认证token"
// @Param	type			query		string	true	"配置类型（当前只支持PricePack）"
// @Param	key				query	string	true	"配置名"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /DeleteConfig [delete]
func (c *CmsController) DeleteConfig() {
	c.callDeleteConfig(func(params *tCmsDeleteConfigParams) (retVal interface{}, errCode string, err error) {
		err = cms.DeleteConfig(params.Ctx, params.Key, params.Type)
		return retVal, "", err
	})
}

// @Title 修改配置
// @Description 修改配置
// @Param	token			header		string	true	"认证token"
// @Param	type			formData	string	true	"配置类型（当前只支持PricePack）"
// @Param	key				formData	string	true	"配置名"
// @Param	value			formData	string	true	"配置值"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /UpdateConfig [put]
func (c *CmsController) UpdateConfig() {
	c.callUpdateConfig(func(params *tCmsUpdateConfigParams) (retVal interface{}, errCode string, err error) {
		retVal, err = cms.UpdateConfig(params.Ctx, params.Key, params.Type, params.Value)
		return retVal, "", err
	})
}

// @Title 查询配置
// @Description 查询配置
// @Param	token			header	string	fasle	"认证token"
// @Param	type			query	string	false	"配置类型（当前只支持PricePack）"
// @Param	key				query	string	false	"配置名"
// @Param	keyword			query	string	false	"关键字"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /QueryConfigs [get]
func (c *CmsController) QueryConfigs() {
	c.callQueryConfigs(func(params *tCmsQueryConfigsParams) (retVal interface{}, errCode string, err error) {
		if params.Key == "FZR" {
			userBind, err := dao.GetUserBindAuthInfo(dao.GetDB(), params.Ctx.GetUserID(), 0, []string{dingding.AuthTypeStaff}, "", "", nil)
			if err != nil {
				return retVal, "", err
			}
			if len(userBind) == model.NO {
				return retVal, "", nil
			}
		}
		retVal, err = cms.QueryConfigs(params.Key, params.Type, params.Keyword)
		return retVal, "", err
	})
}

// @Title 生成二维码或条形码
// @Description 生成二维码或条形码
// @Param	token		header			string	true	"认证token"
// @Param	width		formData		int		true	"图片宽"
// @Param	height		formData		int		true	"图片高"
// @Param	codetype	formData		string	true	"编码类型(二维码：qr; 条形码：bar)"
// @Param	srcData		formData		string	true	"二维码/条形码数据源"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /CreateQrOrBarCode [post]
func (c *CmsController) CreateQrOrBarCode() {
	c.callCreateQrOrBarCode(func(params *tCmsCreateQrOrBarCodeParams) (retVal interface{}, errCode string, err error) {
		retVal, err = jxutils.CreateQrOrBarCode(params.Width, params.Height, params.Codetype, params.SrcData)
		return retVal, "", err
	})
}

// @Title 查询当前系统中已有的城市中的银行支行
// @Description 查询当前系统中已有的城市中的银行支行
// @Param	token			header	string	true	"认证token"
// @Param	cityCode		query	int		false	"城市代码"
// @Param	bankCode		query	string	false	"银行代码"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetCityBankBranches [get]
func (c *CmsController) GetCityBankBranches() {
	c.callGetCityBankBranches(func(params *tCmsGetCityBankBranchesParams) (retVal interface{}, errCode string, err error) {
		retVal, err = cms.GetCityBankBranches(params.Ctx, params.CityCode, params.BankCode)
		return retVal, "", err
	})
}

// @Title 得到平台的账号信息
// @Description 得到平台的账号信息
// @Param	token			header	string	true	"认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetVendorOrgCodeInfo [get]
func (c *CmsController) GetVendorOrgCodeInfo() {
	c.callGetVendorOrgCodeInfo(func(params *tCmsGetVendorOrgCodeInfoParams) (retVal interface{}, errCode string, err error) {
		retVal = apimanager.GetVendorOrgCodeMap(params.Ctx)
		return retVal, "", err
	})
}

// @Title 得到商家与用户之间骑行路线规划
// @Description 得到商家与用户之间骑行路线规划
// @Param	token	header	string	true	"认证token"
// @Param	sLng	query	int	    true	"商家经度"
// @Param	sLat	query	int	    true	"商家纬度"
// @Param	uLng	query	int		true	"用户经度"
// @Param	uLat	query	int		true	"用户纬度"
// @Param	orderId	query	string	false	"订单id"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetSToURidingDistance [get]
func (c *CmsController) GetSToURidingDistance() {
	c.callGetSToURidingDistance(func(params *tCmsGetSToURidingDistanceParams) (retVal interface{}, errCode string, err error) {
		sLng := jxutils.IntCoordinate2Standard(params.SLng)
		sLat := jxutils.IntCoordinate2Standard(params.SLat)
		uLng := jxutils.IntCoordinate2Standard(params.ULng)
		uLat := jxutils.IntCoordinate2Standard(params.ULat)
		retVal, err = cms.GetSToURidingDistance(sLng, sLat, uLng, uLat, params.OrderId)
		return retVal, "", err
	})
}

// @Title 得到商家与用户之间骑行路线规划
// @Description 得到商家与用户之间骑行路线规划
// @Param	token	header	string	true	"认证token"
// @Param	sLng	query	int	    true	"商家经度"
// @Param	sLat	query	int	    true	"商家纬度"
// @Param	uLng	query	int		true	"用户经度"
// @Param	uLat	query	int		true	"用户纬度"
// @Param	orderId	query	string	true	"订单id"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetSToURidingDistance2 [get]
func (c *CmsController) GetSToURidingDistance2() {
	c.callGetSToURidingDistance(func(params *tCmsGetSToURidingDistanceParams) (retVal interface{}, errCode string, err error) {
		sLng := jxutils.IntCoordinate2Standard(params.SLng)
		sLat := jxutils.IntCoordinate2Standard(params.SLat)
		uLng := jxutils.IntCoordinate2Standard(params.ULng)
		uLat := jxutils.IntCoordinate2Standard(params.ULat)
		retVal, err = cms.GetSToURidingDistance2(sLng, sLat, uLng, uLat, params.OrderId, nil)
		return retVal, "", err
	})
}
