package repository

import (
	"strings"

	"be.ems/src/framework/datasource"
	"be.ems/src/framework/logger"
	"be.ems/src/framework/utils/parse"
	"be.ems/src/framework/utils/repo"
	"be.ems/src/modules/chart/model"
)

// 实例化数据层 NewChartGraphImpl 结构体
var NewChartGraphImpl = &ChartGraphImpl{
	selectSql: `select 
	row_id, row_type, row_group,
	id, type, depth, x, y, size, icon, img,
	clip_cfg, direction,
	source, target, combo_id,
	padding, parent_id, children,
	style, label, label_cfg
	from chart_graph`,

	resultMap: map[string]string{
		"row_id":    "RowID",
		"row_type":  "RowType",
		"row_group": "RowGroup",
		"id":        "ID",
		"type":      "Type",
		"depth":     "Depth",
		"x":         "X",
		"y":         "Y",
		"size":      "Size",
		"icon":      "Icon",
		"img":       "Img",
		"clip_cfg":  "ClipCfg",
		"direction": "Direction",
		"source":    "Source",
		"target":    "Target",
		"combo_id":  "ComboID",
		"padding":   "Padding",
		"parent_id": "ParentID",
		"children":  "Children",
		"style":     "Style",
		"label":     "Label",
		"label_cfg": "LabelCfg",
	},
}

// ChartGraphImpl G6关系图数据表 数据层处理
type ChartGraphImpl struct {
	// 查询视图对象SQL
	selectSql string
	// 结果字段与实体映射
	resultMap map[string]string
}

// convertResultRows 将结果记录转实体结果组
func (r *ChartGraphImpl) convertResultRows(rows []map[string]any) []model.ChartGraph {
	arr := make([]model.ChartGraph, 0)
	for _, row := range rows {
		item := model.ChartGraph{}
		for key, value := range row {
			if keyMapper, ok := r.resultMap[key]; ok {
				repo.SetFieldValue(&item, keyMapper, value)
			}
		}
		arr = append(arr, item)
	}
	return arr
}

// SelectPage 根据条件分页查询字典类型
func (r *ChartGraphImpl) SelectPage(query map[string]any) map[string]any {
	// 查询条件拼接
	var conditions []string
	var params []any
	if v, ok := query["rowType"]; ok && v != "" {
		conditions = append(conditions, "row_type = ?")
		params = append(params, strings.Trim(v.(string), " "))
	}
	if v, ok := query["rowGroup"]; ok && v != "" {
		conditions = append(conditions, "row_group = ?")
		params = append(params, strings.Trim(v.(string), " "))
	}

	// 构建查询条件语句
	whereSql := ""
	if len(conditions) > 0 {
		whereSql += " where " + strings.Join(conditions, " and ")
	}

	result := map[string]any{
		"total": 0,
		"rows":  []model.ChartGraph{},
	}

	// 查询数量 长度为0直接返回
	totalSql := "select count(1) as 'total' from chart_graph"
	totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
	if err != nil {
		logger.Errorf("total err => %v", err)
		return result
	}
	total := parse.Number(totalRows[0]["total"])
	if total == 0 {
		return result
	} else {
		result["total"] = total
	}

	// 分页
	pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
	pageSql := " limit ?,? "
	params = append(params, pageNum*pageSize)
	params = append(params, pageSize)

	// 查询数据
	querySql := r.selectSql + whereSql + pageSql
	results, err := datasource.RawDB("", querySql, params)
	if err != nil {
		logger.Errorf("query err => %v", err)
		return result
	}

	// 转换实体
	result["rows"] = r.convertResultRows(results)
	return result
}

// SelectList 根据实体查询
func (r *ChartGraphImpl) SelectList(graph model.ChartGraph) []model.ChartGraph {
	// 查询条件拼接
	var conditions []string
	var params []any
	if graph.RowType != "" {
		conditions = append(conditions, "row_type = ?")
		params = append(params, graph.RowType)
	}
	if graph.RowGroup != "" {
		conditions = append(conditions, "row_group = ?")
		params = append(params, graph.RowGroup)
	}

	// 构建查询条件语句
	whereSql := ""
	if len(conditions) > 0 {
		whereSql += " where " + strings.Join(conditions, " and ")
	}

	// 查询数据
	querySql := r.selectSql + whereSql + " order by depth asc "
	results, err := datasource.RawDB("", querySql, params)
	if err != nil {
		logger.Errorf("query err => %v", err)
	}

	// 转换实体
	return r.convertResultRows(results)
}

// SelectGroup 查询组名
func (r *ChartGraphImpl) SelectGroup() []string {
	rows := []string{}
	// 查询数量 长度为0直接返回
	querySql := "select row_group as 'str' from chart_graph GROUP BY row_group"
	strRows, err := datasource.RawDB("", querySql, nil)
	if err != nil {
		logger.Errorf("Query err => %v", err)
		return rows
	}
	for _, v := range strRows {
		rows = append(rows, v["str"].(string))
	}
	return rows
}

// Insert 批量添加
func (r *ChartGraphImpl) Inserts(graphs []model.ChartGraph) int64 {
	tx := datasource.DefaultDB().CreateInBatches(graphs, 2000)
	if err := tx.Error; err != nil {
		logger.Errorf("CreateInBatches err => %v", err)
	}
	return tx.RowsAffected
}

// Delete 删除组数据
func (r *ChartGraphImpl) DeleteGroup(rowGroup string) int64 {
	tx := datasource.DefaultDB().Where("row_group = ?", rowGroup).Delete(&model.ChartGraph{})
	if err := tx.Error; err != nil {
		logger.Errorf("Delete err => %v", err)
	}
	return tx.RowsAffected
}
