package base

import (
	"git.fsdpf.net/go/contracts"
)

type ResRelation struct {
	Uuid               string `db:"uuid"`
	CategoryUuid       string `db:"category_uuid"`    // 所属 UUID
	Name               string `db:"name"`             // 关联名称
	Code               string `db:"code"`             // 关联标识
	Type               string `db:"type"`             // 关联类型
	ResourceCode       string `db:"actuallyResource"` // 实际资源资源
	RelationForeignKey string `db:"actuallyField"`    // 实际资源资源字段
	RelationResource   string `db:"relationResource"` // 被关联的资源
	RelationField      string `db:"relationField"`    // 被关联的字段
	UpdatedAt          string `db:"updated_at"`
	CreatedAt          string `db:"created_at"`
}

type GetResRelations func(categoryUuid string) []ResRelation

type GetOrmJoinsByResRelations func(root string, items []ResRelation) []contracts.Join

// 获取被关联对象的资源
type GetResRelationResource func(r ResRelation) (contracts.Resource, bool)

// 资源关联依赖
func GetJoinResDependencies(root string, items []ResRelation) (dependencies []string) {
	dependencies = []string{root}

	for {
		done := true
		for _, item := range items {
			if item.Type != "inner" && item.Type != "left" && item.Type != "right" {
				continue
			}

			if dependencies[len(dependencies)-1] == item.Code && item.RelationResource != "" {
				done = false
				dependencies = append(dependencies, item.RelationResource)
			}
		}

		if done {
			break
		}
	}

	return dependencies
}

func GetModelPrefixForRelations(model string, items []ResRelation) (result []any) {
	result = append([]any{model}, result...)
	for _, item := range items {
		if item.Code == model && (item.Type == "hasMany" || item.Type == "hasOne") {
			if item.Type == "hasMany" {
				result = append(result, 0)
			}
			return append(GetModelPrefixForRelations(item.RelationResource, items), result...)
		}
	}
	return result
}

func GetModelJoinsForRelations(model string, items []ResRelation) (result []string) {
	result = append([]string{model}, result...)
	for _, item := range items {
		if item.Code == model && (item.Type == "left" || item.Type == "right" || item.Type == "inner") {
			return append(GetModelJoinsForRelations(item.RelationResource, items), result...)
		}
	}
	return result
}

func GetDataIndexPrefixForRelations(model string, items []ResRelation) (result []any) {
	result = append([]any{model}, result...)
	for _, item := range items {
		if item.Code == model && (item.Type == "hasMany" || item.Type == "hasOne") {
			return append(GetDataIndexPrefixForRelations(item.RelationResource, items), result...)
		}
	}
	return result
}