package model

import (
	"encoding/json"
	"github.com/loveuer/nfflow/internal/sqlType"
)

type InputType int64

const (
	InputTypeES InputType = iota + 1
	InputTypePG
	InputTypeMQ
)

type OutputType int64

const (
	OutputTypeES OutputType = iota + 1
	OutputTypeFile
	OutputTypeMQ
)

type TaskStatus int64

func (t TaskStatus) MarshalJSON() ([]byte, error) {
	return json.Marshal(map[string]any{
		"value": t.Value(),
		"code":  t.Code(),
		"label": t.Label(),
	})
}

func (t TaskStatus) All() []Enum {
	return []Enum{
		TaskStatusNotReady,
		TaskStatusReady,
		TaskStatusRunning,
		TaskStatusSucceed,
		TaskStatusFailed,
	}
}

var _ Enum = TaskStatus(0)

const (
	TaskStatusNotReady TaskStatus = iota
	TaskStatusReady
	TaskStatusRunning
	TaskStatusSucceed
	TaskStatusFailed
)

func (t TaskStatus) Value() int64 {
	return int64(t)
}

func (t TaskStatus) Code() string {
	switch t {
	case TaskStatusNotReady:
		return "not_ready"
	case TaskStatusReady:
		return "ready"
	case TaskStatusRunning:
		return "running"
	case TaskStatusSucceed:
		return "succeed"
	case TaskStatusFailed:
		return "failed"
	default:
		return "unknown"
	}
}

func (t TaskStatus) Label() string {
	switch t {
	case TaskStatusNotReady:
		return "未完善"
	case TaskStatusReady:
		return "等待执行"
	case TaskStatusRunning:
		return "执行中"
	case TaskStatusSucceed:
		return "执行成功"
	case TaskStatusFailed:
		return "执行失败"
	default:
		return "未知"
	}
}

type TaskRunType int64

const (
	TaskRunTypeOnce TaskRunType = iota
	TaskRunTypeTiming
	TaskRunTypeCron
)

func (t TaskRunType) Value() int64 { return int64(t) }

func (t TaskRunType) Code() string {
	switch t {
	case TaskRunTypeOnce:
		return "once"
	case TaskRunTypeTiming:
		return "timing"
	case TaskRunTypeCron:
		return "cron"
	default:
		return "unknown"
	}
}

func (t TaskRunType) Label() string {
	switch t {
	case TaskRunTypeOnce:
		return "手动执行"
	case TaskRunTypeTiming:
		return "定时执行"
	case TaskRunTypeCron:
		return "周期执行"
	default:
		return "未知"
	}
}

func (t TaskRunType) MarshalJSON() ([]byte, error) {
	return json.Marshal(map[string]any{"code": t.Code(), "value": t.Value(), "label": t.Label()})
}

func (t TaskRunType) All() []Enum {
	return []Enum{TaskRunTypeOnce, TaskRunTypeTiming, TaskRunTypeCron}
}

var _ Enum = TaskRunType(0)

type Task struct {
	Id        uint64 `json:"id" gorm:"primaryKey;column:id"`
	CreatedAt int64  `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
	UpdatedAt int64  `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
	DeletedAt int64  `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`

	TaskName    string      `json:"task_name" gorm:"column:task_name;type:varchar(256)"`
	TaskRunType TaskRunType `json:"task_run_type" gorm:"column:task_run_type;type:varchar(16);default:0"` // cron: C-"cron syntax", "once", timestamp: T-1234567890123 毫秒时间戳
	TaskRunAt   int64       `json:"task_run_at" gorm:"column:task_run_at"`
	TaskCron    string      `json:"task_cron" gorm:"column:task_cron;type:varchar(32)"`
	TaskTimeout int         `json:"task_timeout" gorm:"column:task_timeout"`
	TaskStatus  TaskStatus  `json:"task_status" gorm:"column:task_status"`
	TaskLog     string      `json:"task_log" gorm:"task_log"`
}

type Input struct {
	Id          uint64        `json:"id" gorm:"primaryKey;column:id"`
	CreatedAt   int64         `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
	UpdatedAt   int64         `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
	DeletedAt   int64         `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
	InputType   InputType     `json:"input_type"`
	InputConfig sqlType.JSONB `json:"input_config"`
}

type Output struct {
	Id           uint64 `json:"id" gorm:"primaryKey;column:id"`
	CreatedAt    int64  `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
	UpdatedAt    int64  `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
	DeletedAt    int64  `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
	OutputType   OutputType
	OutputConfig sqlType.JSONB
}

type Pipe struct {
	Id        uint64 `json:"id" gorm:"primaryKey;column:id"`
	CreatedAt int64  `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
	UpdatedAt int64  `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
	DeletedAt int64  `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
}