package domain

import (
	"context"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/tool"
	"golang.org/x/exp/slices"
	"sort"
	"strings"
)

type Chart struct {
	Id        int64  // ID
	Pid       int64  // 父级ID
	Type      string // 类型
	Sort      int    // 排序
	Name      string // 名称
	Group     string // 分组
	TenantId  int64  // 租户ID
	Cover     string // 封面
	ChartType string // 图表类型 (记录型表格:RecordTable-1 总体指标:MetricsCard-1 容器卡片:ContainerCard-1 四分图:QuarterChart-1)

	CreatedAt int64 `json:",omitempty"`
	UpdatedAt int64 `json:",omitempty"`
	DeletedAt int64 `json:",omitempty"`
	Version   int   `json:",omitempty"`
}

type ChartRepository interface {
	Insert(ctx context.Context, conn transaction.Conn, dm *Chart) (*Chart, error)
	Update(ctx context.Context, conn transaction.Conn, dm *Chart) (*Chart, error)
	UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Chart) (*Chart, error)
	Delete(ctx context.Context, conn transaction.Conn, dm *Chart) (*Chart, error)
	FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Chart, error)
	Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Chart, error)
	FindOneByGroup(ctx context.Context, conn transaction.Conn, tenantId, pid int64) (*Chart, error)
	FindByTypeAndName(ctx context.Context, conn transaction.Conn, tenantId int64, t string, name string) (int64, []*Chart, error)
}

/*************** 索引函数 开始****************/

func IndexTenantId(tenantId int64) IndexQueryOptionFunc {
	return func() QueryOptions {
		return NewQueryOptions().WithKV("tenantId", tenantId)
	}
}

func IndexChartPid(tenantId, pid int64) IndexQueryOptionFunc {
	return func() QueryOptions {
		return NewQueryOptions().WithKV("tenantId", tenantId).WithKV("pid", pid)
	}
}

func (m *Chart) Identify() interface{} {
	if m.Id == 0 {
		return nil
	}
	return m.Id
}

func (m *Chart) RandName() string {
	randNumber := tool.Krand(6, tool.KC_RAND_KIND_NUM)
	var result strings.Builder
	switch m.Type {
	case ChartTypeReport:
		result.WriteString("未命名报表")
	case ChartTypeGroup:
		result.WriteString("未命名分组")
	case ChartTypeChart:
		result.WriteString("未命名图表")
	}
	result.WriteString(randNumber)
	return result.String()
}

// Reorder 重新排序charts
// appendFlag:true 追加 target 到 charts
// appendFlag:false 不追加
func Reorder(charts []*Chart, target *Chart, appendFlag bool) []*Chart {
	// 重排序
	var result = make([]*Chart, 0)
	sort.SliceStable(charts, func(i, j int) bool {
		return charts[i].Sort < charts[j].Sort
	})
	for index, c := range charts {
		c.Sort = index + 1
		if c.Id == target.Id {
			result = append(result, &Chart{Sort: c.Sort}) // 旧节点继续追击啊,ID设置为0,后面跳过更新
			continue
		}
		result = append(result, c)
	}
	// 插入新的节点
	if appendFlag {
		index := slices.IndexFunc(result, func(c *Chart) bool {
			if float64(c.Sort) > float64(target.Sort)-0.5 {
				return true
			}
			return false
		})
		if index == -1 {
			index = len(result)
		}
		result = slices.Insert(result, index, target)
	}
	// 重排序
	var index = 1
	for i := range result {
		if result[i].Id == 0 {
			continue
		}
		result[i].Sort = index
		index++
	}
	return result
}