package backend

import (
	"bwallet/pkg/errno"
	"bwallet/pkg/handler"
	"bwallet/pkg/util"
	"bwallet/service/coin_service"
	"bwallet/service/coin_ticker_service"
	"bwallet/service/wallet_service"
	"bwallet/validate_service"
	"github.com/Unknwon/com"
	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"
	"strings"
)

func CoinsTicker(c *gin.Context) {
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group

	var platform_id int

	coinTickerService := coin_ticker_service.CoinTicker{}
	if ("administrator" != group) {
		walletService := wallet_service.Wallet{Id: user.UserInfo.PlatformId}
		exists, err := walletService.ExistById()
		if err != nil {
			handler.SendResponse(c, errno.ErrWalletNotFound, nil)
			return
		}

		if (!exists) {
			handler.SendResponse(c, errno.ErrWalletNotFound, nil)
			return
		}

		platform_id = user.UserInfo.PlatformId
	} else {
		if arg := c.Query("platform_id"); arg != "" {
			platform_id = com.StrTo(c.Query("platform_id")).MustInt()
		}
	}

	coinTickerService = coin_ticker_service.CoinTicker{
		PlatformId: platform_id,
	}
	coins_ticker, err := coinTickerService.GetAll()
	if err != nil {
		handler.SendResponse(c, errno.InternalServerError, nil)
		return
	}

	handler.SendResponse(c, nil, coins_ticker)
}

func AddCoinTicker(c *gin.Context) {
	coin_ticker := validate_service.CoinTicker{}
	c.ShouldBindJSON(&coin_ticker)

	if ok, errors := validate_service.ValidateInputs(coin_ticker); !ok {
		for _, err := range errors {
			handler.SendResponse(c, errno.ErrBind, strings.Join(err, " "))
			return
		}
	}
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group

	var platform_id int
	platform_id = user.UserInfo.PlatformId
	if ("administrator" == group) {
		if coin_ticker.PlatformId != 0 {
			platform_id = coin_ticker.PlatformId
		}
	}

	coin_model := coin_service.Coin{Id: coin_ticker.CoinId}
	exists, err := coin_model.ExistById()
	if err != nil {
		handler.SendResponse(c, errno.ErrCoinNotFound, nil)
		return
	}
	if !exists {
		handler.SendResponse(c, errno.ErrCoinNotFound, nil)
		return
	}

	CoinTickerValidateService := coin_ticker_service.CoinTicker{
		CoinName:   coin_ticker.CoinName,
		PlatformId: platform_id,
	}
	exist, _ := CoinTickerValidateService.Exist()
	if exist {
		handler.SendResponse(c, errno.ErrExistCoinTicker, nil)
		return
	}

	CoinTickerService := coin_ticker_service.CoinTicker{
		CoinName:   strings.ToUpper(coin_ticker.CoinName),
		CoinId:     coin_ticker.CoinId,
		Ticker:     coin_ticker.Ticker,
		PlatformId: platform_id,
	}

	if err := CoinTickerService.Add(); err != nil {
		handler.SendResponse(c, errno.ErrAddCoinTicker, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}

func UpdateCoinTicker(c *gin.Context) {
	coin_ticker := validate_service.CoinTicker{}
	c.ShouldBindJSON(&coin_ticker)

	if ok, errors := validate_service.ValidateInputs(coin_ticker); !ok {
		for _, err := range errors {
			handler.SendResponse(c, errno.ErrBind, strings.Join(err, " "))
			return
		}
	}

	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group
	platform_id := user.UserInfo.PlatformId

	if ("administrator" != group && coin_ticker.PlatformId != platform_id) {
		handler.SendResponse(c, errno.ErrUserTokenIncorrect, nil)
		return
	}

	if ("administrator" == group) {
		if coin_ticker.PlatformId != 0 {
			platform_id = coin_ticker.PlatformId
		}
	}

	CoinTickerValidateService := coin_ticker_service.CoinTicker{
		CoinName:   strings.ToUpper(coin_ticker.CoinName),
		PlatformId: platform_id,
	}
	exist, _ := CoinTickerValidateService.Exist()
	if !exist {
		handler.SendResponse(c, errno.ErrCoinTickerNotFound, nil)
		return
	}

	CoinTickerService := coin_ticker_service.CoinTicker{
		CoinName:   strings.ToUpper(coin_ticker.CoinName),
		CoinId:     coin_ticker.CoinId,
		PlatformId: platform_id,
		Ticker:     coin_ticker.Ticker,
	}

	if err := CoinTickerService.Edit(); err != nil {
		handler.SendResponse(c, errno.ErrAddCoinTicker, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}

func DeleteCoinTicker(c *gin.Context) {
	id := com.StrTo(c.DefaultQuery("id", "0")).MustInt()
	valid := validation.Validation{}
	valid.Min(id, 1, "id").Message("ID必须大于0")
	if valid.HasErrors() {
		handler.SendResponse(c, errno.ErrValidation, nil)
		return
	}
	coinTickerService := coin_ticker_service.CoinTicker{Id: id}
	exists, err := coinTickerService.ExistById()
	if err != nil {
		handler.SendResponse(c, errno.ErrValidation, nil)
		return
	}

	if !exists {
		handler.SendResponse(c, errno.ErrCoinTickerNotFound, nil)
		return
	}

	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group
	if ("administrator" != group) {
		ticker, _ := coinTickerService.GetCoinTicker()
		if ticker.PlatformId != user.UserInfo.PlatformId {
			handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
			return
		}
	}

	err = coinTickerService.Delete()
	if err != nil {
		handler.SendResponse(c, errno.ErrDeleteCoinTicker, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}
