package config

import (
	"context"

	"github.com/duke-git/lancet/v2/pointer"

	"github.com/gogf/gf/v2/container/gvar"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gcfg"
)

type Config struct {
	Cfg *gcfg.Config
	Ctx context.Context
}

func (c *Config) GetNotification() (model Notification, err error) {
	model = Notification{
		Platform: c.MustGet("plugin.notification.platform").String(),
		WebHook:  c.MustGet("plugin.notification.webhook").String(),
	}
	return
}

func (c *Config) GetTMallGame() (model TMAll, err error) {
	model = TMAll{
		Gateway:     c.MustGet("OAuth.tMallGame.gateway").String(),
		AppKey:      c.MustGet("OAuth.tMallGame.appKey").String(),
		AppSecret:   c.MustGet("OAuth.tMallGame.appSecret").String(),
		RedirectUri: c.MustGet("OAuth.tMallGame.redirectUri").String(),
	}
	return
}

func (c *Config) GetAgiso() (model Agiso, err error) {
	model = Agiso{
		AppId:     c.MustGet("OAuth.agiso.appId").String(),
		AppSecret: c.MustGet("OAuth.agiso.appSecret").String(),
	}
	return
}

func (c *Config) GetTMallSync() (opts *TMallDataSync) {
	return &TMallDataSync{
		BaseUrl:  c.MustGet("OAuth.sync.baseUrl").String(),
		Interval: c.MustGet("OAuth.sync.interval").Int64(),
		ServerId: c.MustGet("OAuth.sync.serverId").String(),
	}
}

func (c *Config) getDataByKey(key string) (*gvar.Var, error) {
	return c.Cfg.Get(c.Ctx, key)
}

func (c *Config) MustGet(key string) *gvar.Var {
	return c.Cfg.MustGet(c.Ctx, key)
}

func (c *Config) GetAppleCardPostUrl() (string, error) {
	keyA, err := c.getDataByKey("appCard.url")
	if keyA == nil || err != nil {
		return "", err
	}
	keyStr := keyA.String()
	return keyStr, err
}

func (c *Config) GetMysqlAddr() (addr string) {
	addr = c.MustGet("database.v1.link").String()
	return
}

func (c *Config) GetJDCardCfg() (opts JDCardCfg) {
	urlStr := ""
	url := c.MustGet("jdCard.url")
	if !pointer.IsNil(url) {
		urlStr = url.String()
	}
	return JDCardCfg{
		Url: urlStr,
	}
}

func (c *Config) GetAddrCfg() (opts *AddrCfg) {
	merchantAddr := c.MustGet("addr.merchantAddr").String()
	shopAddr := c.MustGet("addr.shopAddr").String()
	return &AddrCfg{
		MerchantAddr: merchantAddr,
		ShopAddr:     shopAddr,
	}
}

func (c *Config) GetTokenOptions() (opts TokenOptions, err error) {
	result, err := c.getDataByKey("token")
	if err != nil {
		return
	}
	if err2 := result.Struct(&opts); err2 != nil {
		err = err2
		return
	}
	return
}

func NewConfig(ctx context.Context) *Config {
	return &Config{
		Cfg: g.Cfg(),
		Ctx: ctx,
	}
}
