package schema

import (
	"database/sql/driver"
	"encoding/json"
	"time"

	"gorm.io/gorm"
)

type ClusterMetering struct {
	gorm.Model

	TenantID  uint64    `gorm:"index;not null"`
	ProjectID uint64    `gorm:"index;not null"`
	ClusterID uint64    `gorm:"not null;index:unq_cid_sts,unique,priority:1"`
	StartTS   time.Time `gorm:"timestamp;index:unq_cid_sts,unique,priority:2"`
	EndTS     time.Time `gorm:"timestamp"`
	Latest    bool      `gorm:"not null;default true"`

	ClusterMeteringStates ClusterMeteringStates `gorm:"type:JSON"`
}

type ClusterMeteringStates struct {
	ClusterStatus     string            `json:"cluster_status"`
	ClusterComponents []*ComponentState `json:"cluster_components"`
}

func (m ClusterMeteringStates) Value() (driver.Value, error) {
	b, err := json.Marshal(m)
	return string(b), err
}

func (m *ClusterMeteringStates) Scan(input any) error {
	return json.Unmarshal(input.([]byte), m)
}

type BillingReportRecord struct {
	gorm.Model

	Data              MeteringReportData `gorm:"type:JSON"`
	Status            string             `gorm:"not null;type:ENUM('synced', 'unsynced')"`
	ClusterMeteringID uint64             `gorm:"not null;default '0';index"`
	TenantID          uint64             `gorm:"not null;index"`
}

type MeteringReportDataItem struct {
	CostID        string            `json:"cost_id"`
	SKU           string            `json:"sku"`
	CostTimeStamp int64             `json:"cost_time_stamp"`
	Cost          int64             `json:"cost"`
	Labels        map[string]string `json:"labels"`
	Memo          string            `json:"memo"`
}

type MeteringReportData struct {
	Items []*MeteringReportDataItem `json:"items"`
}

func (m MeteringReportData) Value() (driver.Value, error) {
	b, err := json.Marshal(m)
	return string(b), err
}

func (m *MeteringReportData) Scan(input any) error {
	return json.Unmarshal(input.([]byte), m)
}
