package models

import (
	"bwallet/pkg/setting"
	"encoding/json"
	"github.com/jinzhu/gorm"
)

type Coin struct {
	Model

	Id             int             `json:"primary_key, id,omitempty"`
	Name           string          `json:"name"`            //简称
	Nickname       json.RawMessage `json:"nickname"`        //全称
	Icon           string          `json:"icon"`            //币种图标
	Introduce      json.RawMessage `json:"introduce"`       //币种介绍
	Official       string          `json:"official"`        //官网
	Paper          string          `json:"paper"`           //白皮书
	Platform       string          `json:"platform"`        //平台
	Chain          string          `json:"chain"`           //主链
	Release        string          `json:"release"`         //发行时间
	AreaSearch     string          `json:"area_search"`     //区块查询
	PublishCount   float64         `json:"publish_count"`   //发行总量
	CirculateCount float64         `json:"circulate_count"` //流通总量
	Decimals       int             `json:"decimals"`        //币种精度
	Address        string          `json:"address"`         //合约地址
	Treaty         int             `json:"treaty"`          //币种类型
	PlatformId     int             `json:"platform_id"`
}

func (c Coin) TableName() string {
	return setting.DatabaseSetting.Name_Sources + ".wallet_coin"
}

/**
 * 通过id检查币种是否存在
 * @param id
 * @return
 */
func ExistCoinById(id int) (bool, error) {
	var coin Coin
	err := db.Select("id").Where("id = ?", id).First(&coin).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return false, err
	}

	if coin.ID > 0 {
		return true, nil
	}

	return false, nil
}

/**
 * 获取符合条件的信息总数
 * @param id
 * @return
 */
func GetCoinTotal(maps interface{}) (int, error) {
	var count int
	if err := db.Model(&Coin{}).Where(maps).Count(&count).Error; err != nil {
		return 0, err
	}

	return count, nil
}

/**
 * 获取符合条件的信息
 * @param id
 * @return
 */
func GetCoins(pageNum, pageSize int, maps interface{}) ([]*Coin, error) {
	var coins []*Coin

	err := db.Where(maps).Offset(pageNum).Limit(pageSize).Find(&coins).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return coins, nil
}

func Find(name string, chain string) (*Coin, error) {
	var coin Coin

	err := db.Debug().Where("name = ? and chain = ?", name, chain).First(&coin).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	err = db.Model(&coin).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return &coin, nil
}

/**
 * 通过id获取指定币种信息
 * @param id
 * @return
 */
func GetCoin(id int) (*Coin, error) {
	var coin Coin
	err := db.Where("id = ?", id).First(&coin).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	err = db.Model(&coin).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return &coin, nil
}

/**
 * 添加币种信息
 * @param
 * @return
 */
func AddCoin(data map[string]interface{}) (error) {
	coin := Coin{
		Name:           data["name"].(string),
		Nickname:       data["nickname"].(json.RawMessage),
		Icon:           data["icon"].(string),
		Introduce:      data["introduce"].(json.RawMessage),
		Official:       data["official"].(string),
		Paper:          data["paper"].(string),
		Platform:       data["platform"].(string),
		Chain:          data["chain"].(string),
		Release:        data["release"].(string),
		AreaSearch:     data["area_search"].(string),
		PublishCount:   data["publish_count"].(float64),
		CirculateCount: data["circulate_count"].(float64),
		Decimals:       data["decimals"].(int),
		Address:        data["address"].(string),
		PlatformId:     data["platform_id"].(int),
		Treaty:         data["treaty"].(int),
	}
	if err := db.Create(&coin).Error; err != nil {
		return err
	}

	return nil
}

/**
 * 更新币种信息
 * @param
 * @return
 */
func EditCoin(id int, data interface{}) error {
	if err := db.Model(&Coin{}).Where("id = ?", id).Updates(data).Error; err != nil {
		return err
	}

	return nil
}

/**
 * 删除币种信息
 * @param
 * @return
 */
func DeleteCoin(id int) error {
	if err := db.Where("id = ?", id).Delete(Coin{}).Error; err != nil {
		return err
	}

	return nil
}

func GetCoinsPlatform() ([]*Coin, error) {
	var coins []*Coin
	err := db.Select("platform").Where("platform <> ?", "").Group("platform").Find(&coins).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return coins, nil
}
