package model

import (
	"strconv"

	"gorm.io/gorm"

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

const (
	Viewer   string = "Viewer"
	Approver string = "Approver"
)

const (
	JobPhasePending string = "Pending"

	JobPhaseWaiting string = "WaitingForApproval"

	JobPhaseRunning string = "Running"

	JobPhaseSuccess string = "Success"

	JobPhaseFailed string = "Failed"

	JobPhaseDeleted string = "Canceled"
)

func UpdateJobStatusByID(id, newStatus string) error {
	return db.Transaction(func(tx *gorm.DB) error {
		return tx.Model(&db.OperationJob{}).Where("job_id=?", id).Update("status", newStatus).Error
	})
}

func CreateJobRecord(job *db.OperationJob) error {
	return db.Transaction(func(tx *gorm.DB) error {
		return job.Create(tx)
	})
}

func ListJobByClusterID(id uint64) ([]db.OperationJob, error) {
	clusterId := strconv.FormatUint(id, 10)
	var result []db.OperationJob
	err := db.Transaction(func(tx *gorm.DB) error {
		return db.NewOperationJobQuerySet(tx).ClusterIDEq(clusterId).All(&result)
	})
	if err != nil {
		return nil, err
	}
	return result, nil
}

func GetJobDetail(jobID uint) (*db.OperationJob, error) {
	var result *db.OperationJob
	err := db.Transaction(func(tx *gorm.DB) error {
		return db.NewOperationJobQuerySet(tx).IDEq(jobID).One(result)
	})
	if err != nil {
		return nil, err
	}
	return result, nil
}

func GetClusterRunningJob(clusterId string) (*db.OperationJob, error) {
	var result *db.OperationJob
	err := db.Transaction(func(tx *gorm.DB) error {
		return db.NewOperationJobQuerySet(tx).ClusterIDEq(clusterId).StatusEq(JobPhaseRunning).One(result)
	})
	return result, err
}

func GetUserRole(email string) (string, error) {
	var result *db.Approver
	err := db.Transaction(func(tx *gorm.DB) error {
		return db.NewApproverQuerySet(tx).EmailEq(email).One(result)
	})
	if result == nil {
		return Viewer, err
	}
	return Approver, nil
}
