package model

import (
	"errors"
	"github.com/fonchain_enterprise/fonchain-approval/pkg/m"
	"gorm.io/plugin/soft_delete"
	"time"
)

// ApprovalWorkFlow 审批流
type ApprovalWorkFlow struct {
	ID         uint64                `gorm:"primaryKey;column:id" json:"id"`
	DeletedAt  soft_delete.DeletedAt `gorm:"column:deleted_at" json:"deletedAt"`
	CreatedAt  time.Time             `gorm:"column:created_at" json:"createdAt"`
	UpdatedAt  time.Time             `gorm:"column:updated_at" json:"updatedAt"`
	ApprovalID uint64                `gorm:"column:approval_id" json:"approvalId"`
	UserId     uint64                `gorm:"column:user_id" json:"userId"`
	Name       string                `gorm:"column:name" json:"name"`
	Level      uint8                 `gorm:"column:level" json:"Level"`
	Status     uint8                 `gorm:"column:status" json:"Status"`
	Reply      string                `gorm:"column:reply" json:"Reply"`
	OperatedAt *time.Time            `gorm:"column:operated_at" json:"operatedAt"`
}

func GetNowWorkFlowByApprovalId(approvalId uint64) (*ApprovalWorkFlow, error) {
	var workFlow *ApprovalWorkFlow

	if err := DB.Model(&ApprovalWorkFlow{}).
		Where(&ApprovalWorkFlow{ApprovalID: approvalId, Status: StatusDoing}).
		Order("level asc").First(&workFlow).Error; err != nil {
		return nil, err
	}

	return workFlow, nil

}

func GetWorkFlowByLevel(approvalId uint64, level uint8) (*ApprovalWorkFlow, error) {
	var workFlow *ApprovalWorkFlow

	if err := DB.Model(&ApprovalWorkFlow{}).Where(&ApprovalWorkFlow{ApprovalID: approvalId, Level: level}).First(&workFlow).Error; err != nil {
		return nil, err
	}

	return workFlow, nil

}

func BatchSave(users ApprovalUsers, approvalId uint64) error {
	var insertRaws []*ApprovalWorkFlow

	if users == nil && len(users) == 0 {
		return errors.New(m.ErrorNotFound)
	}

	for index, user := range users {
		temp := &ApprovalWorkFlow{
			UserId:     user.ID,
			Name:       user.Name,
			ApprovalID: approvalId,
			Status:     StatusDoing,
			Level:      uint8(index + 1),
		}

		insertRaws = append(insertRaws, temp)

	}

	return DB.Create(&insertRaws).Error
}

func (m *ApprovalWorkFlow) TableName() string {
	return "approval_workflow"
}

func (m *ApprovalWorkFlow) Pass(replay string) error {
	return m.SetStatus(StatusOk, replay)
}

func (m *ApprovalWorkFlow) Refuse(replay string) error {
	return m.SetStatus(StatusFail, replay)
}

func (m *ApprovalWorkFlow) SetStatus(status uint8, reply string) error {
	m.Status = status
	m.Reply = reply
	temp := time.Now()
	m.OperatedAt = &temp
	DB.Save(m)
	return DB.Save(m).Error
}