package model

import (
	"time"

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

// HealthCheckRepository defines the interface for health check database operations
type HealthCheckRepository interface {
	// Strategy operations
	InsertHealthCheckStrategy(strategy *db.HealthCheckStrategy) error
	GetHealthCheckStrategyByUUID(uuid string) (*db.HealthCheckStrategy, error)
	ListHealthCheckStrategies(clusterID, dbaasOrgID string, page, perPage int) ([]db.HealthCheckStrategy, int64, error)
	UpdateHealthCheckStrategy(strategy *db.HealthCheckStrategy) error
	DeleteHealthCheckStrategy(uuid string) error
	ListPendingCronHealthCheckStrategies() ([]db.HealthCheckStrategy, error)
	UpdateHealthCheckStrategyLastRun(uuid string, lastRunAt, nextRunAt *time.Time) error
	UpdateHealthCheckStrategyStatus(uuid, status, errorMsg string) error

	// Result operations
	InsertHealthCheckResult(result *db.HealthCheckResult) error
	GetHealthCheckResultByUUID(uuid string) (*db.HealthCheckResult, error)
	ListHealthCheckResults(clusterID, dbaasOrgID string, page, perPage int) ([]db.HealthCheckResult, int64, error)
	ListPendingHealthCheckResults() ([]*db.HealthCheckResult, error)
	UpdateHealthCheckResult(result *db.HealthCheckResult) error
	UpdateHealthCheckResultStatus(uuid, status, errorMsg string) error
	DeleteHealthCheckResult(uuid string) error
	FetchPendingOrRunningHealthCheckJobs(results *[]*db.HealthCheckResult) error
	FetchPendingOrRunningHealthCheckJobsBatch(results *[]*db.HealthCheckResult, limit int, excludeUUIDs []string) error
	CountPendingOrRunningHealthCheckJobs(excludeUUIDs []string) (int64, error)
}

// Ensure HealthCheckDB implements HealthCheckRepository
var _ HealthCheckRepository = (*HealthCheckDB)(nil)

// HealthCheckDB implements HealthCheckRepository using real database
type HealthCheckDB struct{}

// NewHealthCheckDB creates a new HealthCheckDB instance
func NewHealthCheckDB() *HealthCheckDB {
	return &HealthCheckDB{}
}

// Strategy operations
func (d *HealthCheckDB) InsertHealthCheckStrategy(strategy *db.HealthCheckStrategy) error {
	return InsertHealthCheckStrategy(strategy)
}

func (d *HealthCheckDB) GetHealthCheckStrategyByUUID(uuid string) (*db.HealthCheckStrategy, error) {
	return GetHealthCheckStrategyByUUID(uuid)
}

func (d *HealthCheckDB) ListHealthCheckStrategies(clusterID, dbaasOrgID string, page, perPage int) ([]db.HealthCheckStrategy, int64, error) {
	return ListHealthCheckStrategies(clusterID, dbaasOrgID, page, perPage)
}

func (d *HealthCheckDB) UpdateHealthCheckStrategy(strategy *db.HealthCheckStrategy) error {
	return UpdateHealthCheckStrategy(strategy)
}

func (d *HealthCheckDB) DeleteHealthCheckStrategy(uuid string) error {
	return DeleteHealthCheckStrategy(uuid)
}

func (d *HealthCheckDB) ListPendingCronHealthCheckStrategies() ([]db.HealthCheckStrategy, error) {
	return ListPendingCronHealthCheckStrategies()
}

func (d *HealthCheckDB) UpdateHealthCheckStrategyLastRun(uuid string, lastRunAt, nextRunAt *time.Time) error {
	return UpdateHealthCheckStrategyLastRun(uuid, lastRunAt, nextRunAt)
}

func (d *HealthCheckDB) UpdateHealthCheckStrategyStatus(uuid, status, errorMsg string) error {
	return UpdateHealthCheckStrategyStatus(uuid, status, errorMsg)
}

// Result operations
func (d *HealthCheckDB) InsertHealthCheckResult(result *db.HealthCheckResult) error {
	return InsertHealthCheckResult(result)
}

func (d *HealthCheckDB) GetHealthCheckResultByUUID(uuid string) (*db.HealthCheckResult, error) {
	return GetHealthCheckResultByUUID(uuid)
}

func (d *HealthCheckDB) GetHealthCheckResultByScope(dbaasOrgID, clusterID, uuid string) (*db.HealthCheckResult, error) {
	return GetHealthCheckResultByScope(dbaasOrgID, clusterID, uuid)
}

func (d *HealthCheckDB) ListHealthCheckResultsByScope(
	dbaasOrgID, clusterID string,
	options HealthCheckResultListOptions,
) ([]db.HealthCheckResult, int64, error) {
	return ListHealthCheckResultsByScope(dbaasOrgID, clusterID, options)
}

func (d *HealthCheckDB) ListHealthCheckResults(clusterID, dbaasOrgID string, page, perPage int) ([]db.HealthCheckResult, int64, error) {
	return ListHealthCheckResults(clusterID, dbaasOrgID, page, perPage)
}

func (d *HealthCheckDB) ListPendingHealthCheckResults() ([]*db.HealthCheckResult, error) {
	return ListPendingHealthCheckResults()
}

func (d *HealthCheckDB) UpdateHealthCheckResult(result *db.HealthCheckResult) error {
	return UpdateHealthCheckResult(result)
}

func (d *HealthCheckDB) UpdateHealthCheckResultStatus(uuid, status, errorMsg string) error {
	return UpdateHealthCheckResultStatus(uuid, status, errorMsg)
}

func (d *HealthCheckDB) DeleteHealthCheckResult(uuid string) error {
	return DeleteHealthCheckResult(uuid)
}

func (d *HealthCheckDB) FetchPendingOrRunningHealthCheckJobs(results *[]*db.HealthCheckResult) error {
	return FetchPendingOrRunningHealthCheckJobs(results)
}

func (d *HealthCheckDB) FetchPendingOrRunningHealthCheckJobsBatch(results *[]*db.HealthCheckResult, limit int, excludeUUIDs []string) error {
	return FetchPendingOrRunningHealthCheckJobsBatch(results, limit, excludeUUIDs)
}

func (d *HealthCheckDB) CountPendingOrRunningHealthCheckJobs(excludeUUIDs []string) (int64, error) {
	return CountPendingOrRunningHealthCheckJobs(excludeUUIDs)
}
