package model

import (
	"database/sql/driver"
	"fmt"
	"time"
)

/* code 结构体 */
type CodeData struct {
	Code   string `form:"code" binding:"required"`
	Gid    string `form:"gid" binding:"required"`
	Pf     string `form:"pf" binding:"required"`
	Secret string `form:"secret"`
}

type Users struct {
	ID     int    `json:"id" gorm:"not null;"`
	OpenId string `json:"openId" gorm:"not null;column:openId;"`
	Pf     string `json:"pf" gorm:"not null;"`
	UserId int    `json:"userId" gorm:"not null;column:userId;"`

	CreatedAt time.Time `json:"createdAt" gorm:"column:createdAt;"`
	UpdatedAt time.Time `json:"updatedAt" gorm:"column:updatedAt;"`
}

type User struct {
	ID        int       `json:"id" gorm:"not null;"`
	Pf        string    `json:"pf" gorm:"not null;"`
	Gid       string    `json:"gid" gorm:"not null;"`
	UserId    int       `json:"userId" gorm:"not null;column:userId;"`
	OpenId    string    `json:"openId" gorm:"not null;column:openId;"`
	CreatedAt time.Time `json:"createdAt" gorm:"column:createdAt;"`
}

type UserLogin struct {
	ID        int       `json:"id" gorm:"not null;"`
	Pf        string    `json:"pf" gorm:"not null;"`
	Gid       string    `json:"gid" gorm:"not null;"`
	UserId    int       `json:"userId" gorm:"not null;column:userId;"`
	LoginTime time.Time `json:"loginTime" gorm:"column:loginTime;"`
}

type UserOnline struct {
	ID      int       `json:"id" gorm:"not null;"`
	Pf      string    `json:"pf" gorm:"not null;"`
	Gid     string    `json:"gid" gorm:"not null;"`
	Type    int       `json:"type" gorm:"not null;"`
	UserId  int       `json:"userId" gorm:"not null;column:userId;"`
	LogTime time.Time `json:"logTime" gorm:"column:logTime;"`
}

type Admin struct {
	ID        int       `json:"id" gorm:"not null;"`
	Account   string    `json:"account" gorm:"not null;"`
	Password  string    `json:"password" gorm:"not null;"`
	Name      string    `json:"name" gorm:"not null;"`
	CreatedAt time.Time `json:"createdAt" gorm:"column:createdAt;"`
	UpdatedAt time.Time `json:"updatedAt" gorm:"column:updatedAt;"`
}

type UserSeeAds struct {
	ID        int    `json:"id" gorm:"not null;"`
	Pf        string `json:"pf" gorm:"not null;"`
	Gid       string `json:"gid" gorm:"not null;"`
	UserId    int    `json:"userId" gorm:"not null;column:userId;"`
	Date      string `json:"date" gorm:"not null;"`
	CreatedAt XTime  `json:"createdAt" gorm:"column:createdAt;"`
	StartTime XTime  `json:"startTime" gorm:"column:startTime;"`
	AdsId     string `json:"adsId" gorm:"not null;column:adsId;"`
	AdsType   string `json:"adsType" gorm:"not null;column:adsType;"`
	AdsScene  string `json:"adsScene" gorm:"not null;column:adsScene;"`
	AdsState  int    `json:"adsState" gorm:"not null;column:adsState;"`
}

// 1. 创建 time.Time 类型的副本 XTime；
type XTime struct {
	time.Time
}

// 2. 为 Xtime 重写 MarshaJSON 方法，在此方法中实现自定义格式的转换；
func (t XTime) MarshalJSON() ([]byte, error) {
	output := fmt.Sprintf("\"%s\"", t.Format("2006-01-02 15:04:05"))
	return []byte(output), nil
}

// 3. 为 Xtime 实现 Value 方法，写入数据库时会调用该方法将自定义时间类型转换并写入数据库；
func (t XTime) Value() (driver.Value, error) {
	var zeroTime time.Time
	if t.Time.UnixNano() == zeroTime.UnixNano() {
		return nil, nil
	}
	return t.Time, nil
}

// 4. 为 Xtime 实现 Scan 方法，读取数据库时会调用该方法将时间数据转换成自定义时间类型；
func (t *XTime) Scan(v interface{}) error {
	value, ok := v.(time.Time)
	if ok {
		*t = XTime{Time: value}
		return nil
	}
	return fmt.Errorf("can not convert %v to timestamp", v)
}

type GameAction struct {
	ID         int    `json:"id" gorm:"not null;"`
	Gid        string `json:"gid" gorm:"not null;"`
	ActionId   string `json:"actionId" gorm:"not null;column:actionId;"`
	ActionName string `json:"actionName" gorm:"not null;column:actionName;"`
	Status     int    `json:"status" gorm:"not null;column:status;"`
	Remark     string `json:"remark" gorm:"not null;column:remark;"`
	CreatedAt  XTime  `json:"createdAt" gorm:"column:createdAt;type:date;"`
	UpdatedAt  XTime  `json:"updatedAt" gorm:"column:updatedAt;type:date;"`
}

type GameActionOption struct {
	ID         int    `json:"id" gorm:"not null;"`
	ActionId   int    `json:"actionId" gorm:"not null;column:actionId;"`
	OptionId   string `json:"optionId" gorm:"not null;column:optionId;"`
	OptionName string `json:"optionName" gorm:"not null;column:optionName;"`
	OptionType string `json:"optionType" gorm:"not null;column:optionType;"`
	Status     int    `json:"status" gorm:"not null;column:status;"`
	CreatedAt  XTime  `json:"createdAt" gorm:"column:createdAt;"`
	UpdatedAt  XTime  `json:"updatedAt" gorm:"column:updatedAt;"`
}

type UserAction struct {
	ID        int    `json:"id" gorm:"not null;"`
	Pf        string `json:"pf" gorm:"not null;"`
	Gid       string `json:"gid" gorm:"not null;"`
	ActionId  string `json:"actionId" gorm:"not null;column:actionId;"`
	UserId    int    `json:"userId" gorm:"not null;column:userId;"`
	CreatedAt XTime  `json:"createdAt" gorm:"column:createdAt;type:date;"`
	Data      string `json:"data" gorm:"not null;column:data;"`
}

type UserActionOption struct {
	ID           int    `json:"id" gorm:"not null;"`
	OptionId     string `json:"optionId" gorm:"not null;column:optionId;"`
	Value        string `json:"value" gorm:"not null;column:value;"`
	CreatedAt    XTime  `json:"createdAt" gorm:"column:createdAt;type:date;"`
	UserActionId int    `json:"userActionId" gorm:"not null;column:userActionId;"`
}
