package repo

import (
	"context"
	"fmt"
	"time"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"

	"github.com/pingcap-inc/clinic_cloud_server/pkg/db"
)

type AlertNotificationRepo struct{}

func (repo *AlertNotificationRepo) Save(ctx context.Context,
	item *db.AlertNotification,
) error {
	wdb := db.GetDB()
	err := wdb.Save(item).Error
	if err != nil {
		return fmt.Errorf("save alert notification %d failed: %w", item.ID, err)
	}
	return nil
}

func (repo *AlertNotificationRepo) BatchSave(ctx context.Context, items []*db.AlertNotification) error {
	if len(items) == 0 {
		return nil
	}
	wdb := db.GetDB().Model(&db.AlertNotification{})
	err := wdb.Clauses(clause.OnConflict{
		UpdateAll: true,
	}).Create(items).Error
	if err != nil {
		return fmt.Errorf("batch save alert notification failed: %w", err)
	}
	return nil
}

type AlertNotificationQuery struct {
	TenantId  uint64
	ProjectId uint64
	ClusterId uint64
	StartTime *time.Time
	EndTime   *time.Time
	Page      int
	PageSize  int
}

func (q AlertNotificationQuery) Build(tx *gorm.DB) *gorm.DB {
	if q.ClusterId != 0 {
		tx = tx.Where("cluster_id = ?", q.ClusterId)
	} else if q.ProjectId != 0 {
		tx = tx.Where("project_id = ?", q.ProjectId)
	} else if q.TenantId != 0 {
		tx = tx.Where("tenant_id = ?", q.TenantId)
	}
	if q.StartTime != nil {
		tx = tx.Where("created_at >= ?", q.StartTime)
	}
	if q.EndTime != nil {
		tx = tx.Where("created_at <= ?", q.EndTime)
	}
	return tx
}

func (repo *AlertNotificationRepo) Count(ctx context.Context,
	query AlertNotificationQuery,
) (int64, error) {
	rdb := db.GetDB().Model(&db.AlertNotification{})
	rdb = query.Build(rdb)
	var count int64
	err := rdb.Count(&count).Error
	if err != nil {
		return 0, fmt.Errorf("count alert notifications failed: %w", err)
	}
	return count, nil
}

func (repo *AlertNotificationRepo) Query(ctx context.Context,
	query AlertNotificationQuery,
) ([]*db.AlertNotification, error) {
	if query.Page <= 0 {
		query.Page = 1
	}
	if query.PageSize <= 0 {
		query.PageSize = 10
	}

	rdb := db.GetDB().Model(&db.AlertNotification{})
	rdb = query.Build(rdb)
	rdb.Offset((query.Page - 1) * query.PageSize).Limit(query.PageSize)

	items := make([]*db.AlertNotification, 0)
	err := rdb.Find(&items).Error
	if err != nil {
		return nil, fmt.Errorf("query alert notifications failed: %w", err)
	}
	return items, nil
}
