package biz

import (
	"context"
	"time"
)

type DictionaryDetail struct {
	ID           uint
	CreatedAt    time.Time
	UpdatedAt    time.Time
	Label        string
	Value        string
	Extend       string
	Status       *bool
	Sort         int
	DictionaryID uint
	ParentID     *uint
	Level        int
	Path         string
	Children     []*DictionaryDetail
}

type DictionaryDetailFilter struct {
	DictionaryID uint
	Label        string
	Value        string
	Status       *bool
	ParentID     *uint
	Level        *int
}

type DictionaryDetailRepo interface {
	CreateDictionaryDetail(context.Context, *DictionaryDetail) error
	UpdateDictionaryDetail(context.Context, *DictionaryDetail) error
	DeleteDictionaryDetail(context.Context, uint) error
	FindDictionaryDetail(context.Context, uint) (*DictionaryDetail, error)
	ListDictionaryDetails(context.Context, int, int, DictionaryDetailFilter) ([]*DictionaryDetail, int64, error)
	DictionaryDetailTree(context.Context, uint, string) ([]*DictionaryDetail, error)
	DictionaryDetailsByParent(context.Context, uint, *uint, bool) ([]*DictionaryDetail, error)
}

type Dictionary struct {
	ID        uint
	CreatedAt time.Time
	UpdatedAt time.Time
	Name      string
	Type      string
	Status    *bool
	Desc      string
	ParentID  *uint
	Children  []*Dictionary
	Details   []*DictionaryDetail
}

type DictionaryRepo interface {
	DictionaryMetadataRepo
	DictionaryDetailRepo
}

type DictionaryUsecase struct{ DictionaryRepo }

func NewDictionaryUsecase(repo DictionaryRepo) *DictionaryUsecase {
	return &DictionaryUsecase{DictionaryRepo: repo}
}

type DictionaryMetadataRepo interface {
	CreateDictionary(context.Context, *Dictionary) error
	ImportDictionary(context.Context, *Dictionary, []*DictionaryDetail) error
	UpdateDictionary(context.Context, *Dictionary) error
	DeleteDictionary(context.Context, uint) error
	FindDictionary(context.Context, uint, string, *bool, bool) (*Dictionary, error)
	ExportDictionary(context.Context, uint) (*Dictionary, error)
	ListDictionaries(context.Context, int, int, string, string, bool) ([]*Dictionary, int64, error)
}

func (uc *DictionaryUsecase) ImportDictionary(ctx context.Context, dictionary *Dictionary, details []*DictionaryDetail) error {
	return uc.DictionaryRepo.ImportDictionary(ctx, dictionary, details)
}

func (uc *DictionaryUsecase) DictionaryDetailsByParent(ctx context.Context, dictionaryID uint, parentID *uint, includeChildren bool) ([]*DictionaryDetail, error) {
	return uc.DictionaryRepo.DictionaryDetailsByParent(ctx, dictionaryID, parentID, includeChildren)
}
