package mysql

import (
	"context"
	"time"

	"gorm.io/gorm"

	v1 "github.com/pingcap-inc/pchub/model/v1"
)

type costAlert struct {
	db *gorm.DB
}

func newCostAlert(ds *datastore) *costAlert {
	return &costAlert{db: ds.db}
}

func (ca *costAlert) ListAllActives(_ context.Context) (*[]v1.CostAlertRule, error) {
	var res []v1.CostAlertRule
	err := ca.db.
		Preload("Resource").
		Where("startDate IS NULL OR startDate <= ?", time.Now().UTC()).
		Find(&res).
		Order("resourceID desc, threshold desc").
		Error

	return &res, err
}

func (ca *costAlert) ListByResourceID(_ context.Context, resourceID uint64) (*[]v1.CostAlertRule, error) {
	var res []v1.CostAlertRule
	err := ca.db.Model(&v1.CostAlertRule{}).Where("resourceID = ?", resourceID).Scan(&res).Error

	return &res, err
}

func (ca *costAlert) ListByResourceMngID(_ context.Context, resourceMngID string) (*[]v1.CostAlertRule, error) {
	var res []v1.CostAlertRule
	err := ca.db.Model(&v1.CostAlertRule{}).Joins("Resource").Where("Resource.managementID = ?", resourceMngID).Order("cost_alert_rule.createdAt DESC").Scan(&res).Error

	return &res, err
}

func (ca *costAlert) Create(_ context.Context, costAlert *v1.CostAlertRule) error {
	return ca.db.Create(costAlert).Error
}

func (ca *costAlert) Update(_ context.Context, costAlert *v1.CostAlertRule) error {
	return ca.db.Save(costAlert).Error
}

func (ca *costAlert) Delete(_ context.Context, costAlert *v1.CostAlertRule) error {
	model := ca.db
	if costAlert.ID != 0 {
		model = model.Where("id = ?", costAlert.ID)
	}
	if costAlert.ResourceID != 0 {
		model = model.Where("resourceID = ?", costAlert.ResourceID)
	}
	err := model.Delete(&v1.CostAlertRule{}).Error

	return err
}

func (ca *costAlert) GetByID(ctx context.Context, id uint64) (*v1.CostAlertRule, error) {
	var res v1.CostAlertRule
	err := ca.db.Model(&v1.CostAlertRule{}).Joins("Resource").Where("cost_alert_rule.id = ?", id).First(&res).Error

	return &res, dbNotFoundErrorWrap(err)
}
