package controllers

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/json"
	"errors"
	"git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/jxstore/common"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/partner/purchase/tiktok_store"
	"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"
	"strings"
)

type TiktokShopController struct {
	web.Controller
}

func AesDecrypt(msgSecret, appSecret string) (string, error) {
	var appSecretArr = []byte(strings.ReplaceAll(appSecret, "-", ""))
	bytesPass, err := base64.StdEncoding.DecodeString(msgSecret)
	if err != nil {
		return "", errors.New("解密失败！！！")
	}
	sourceMsg, err := DoAesDecrypt(bytesPass, appSecretArr)
	if err != nil {
		return "", errors.New("解密失败！！！")
	}
	return string(sourceMsg), nil
}

func DoAesDecrypt(encryptedMsg, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	//AES分组长度为128位，所以blockSize=16，单位字节
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) //初始向量的长度必须等于块block的长度16字节
	origData := make([]byte, len(encryptedMsg))
	blockMode.CryptBlocks(origData, encryptedMsg)
	origData = PKCS5UnPadding(origData)
	return origData, nil
}

func PKCS5UnPadding(origData []byte) []byte {
	length := len(origData)
	unfilledNum := int(origData[length-1])
	return origData[:(length - unfilledNum)]
}

type Code struct {
	MsgType int64  `json:"msg_type"`
	Msg     string `json:"msg"`
}

type MsgDetail struct {
	ActionType       int    `json:"action_type"`
	AppId            int64  `json:"app_id"`
	ShopId           int    `json:"shop_id"`
	Code             string `json:"code"`
	CodeGenerateTime string `json:"code_generate_time"`
}

func (c *TiktokShopController) TokenMsg() {
	req := c.Ctx.Request
	var code string
	switch req.Method {
	case http.MethodPost:
		data, err := ioutil.ReadAll(req.Body)
		if err != nil {
			c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
			c.ServeJSON()
			return
		}

		codeToken, err := AesDecrypt(string(data), globals.TiktokShopAppSecret)
		if err != nil {
			c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
			c.ServeJSON()
		}

		var codeMsg Code
		if err := json.Unmarshal([]byte(codeToken), &codeMsg); err != nil {
			c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
			c.ServeJSON()
			return
		}

		var msg MsgDetail
		if err := json.Unmarshal([]byte(codeMsg.Msg), &msg); err != nil {
			c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
			c.ServeJSON()
			return
		}
		code = msg.Code
	case http.MethodGet:
		codeValues := req.URL.Query()
		codeList := codeValues.Get("code")

		if err := json.Unmarshal([]byte(string(codeList)), &code); err != nil {
			c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
			c.ServeJSON()
			return
		}
	}

	if len(code) == 0 {
		c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
		c.ServeJSON()
		return
	}

	result, err := api.TiktokStore.CreateToken(code)
	if err != nil {
		c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
		c.ServeJSON()
		return
	}

	data, err := json.Marshal(result)
	if err != nil {
		c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
		c.ServeJSON()
		return
	}

	param := &model.VendorOrgCode{
		VendorID:       model.VendorIDDD,
		VendorOrgCode:  utils.Int64ToStr(result.ShopId),
		Comment:        result.ShopName,
		VendorType:     "platform",
		IsJxCat:        1,
		IsOpen:         1,
		EmpowerURL:     "https://fuwu.jinritemai.com/detail?from=open_partner_svcList&service_id=24070",
		StoreBrandName: result.ShopName,
		Token:          string(data),
		AppKey:         "",
		AppSecret:      "",
	}
	if err := common.AddVendorOrgCode(nil, param); err != nil {
		c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
		c.ServeJSON()
		return
	}
	if param.VendorOrgCode == "68023619" {
		tiktok_store.HttpToGuoYuan(utils.Struct2Map(param, "", false), tiktok_store.CaiShiPushGyTagToken, model.ServerTypePet)
	}

	c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackSuccessCode, Msg: tiktok_api.CallbackSuccess}
	c.ServeJSON()
}

// JxcsToGyTiktokToken 果园京西速食接受token更新
func (c *TiktokShopController) JxcsToGyTiktokToken() {
	data, err := ioutil.ReadAll(c.Ctx.Request.Body)
	if err != nil {
		c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
		c.ServeJSON()
		return
	}
	param := &model.VendorOrgCode{}
	if err := json.Unmarshal(data, param); err != nil {
		c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
		c.ServeJSON()
		return
	}

	if err := common.AddVendorOrgCode(nil, param); err != nil {
		c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackFailCode, Msg: tiktok_api.CallbackFail}
		c.ServeJSON()
		return
	}

	c.Data["json"] = tiktok_api.CallbackResponse{Code: tiktok_api.CallbackSuccessCode, Msg: tiktok_api.CallbackSuccess}
	c.ServeJSON()
}
