package InfoCollection

import (
	"ColdVerify_server/lib"
	"ColdVerify_server/logs"
	"errors"
	"fmt"
	_ "github.com/astaxie/beego/cache/redis"
	"github.com/beego/beego/v2/adapter/orm"
	orm2 "github.com/beego/beego/v2/client/orm"
	_ "github.com/go-sql-driver/mysql"
	"strconv"
	"strings"
)

// 模版
type InfoTemplateClass struct {
	Id     int    `orm:"column(ID);size(11);auto;pk"`
	T_fid  int    `orm:"size(200);null"` // 父级分类ID，主类 为 0
	T_name string `orm:"size(256);null"` // 标题
	T_path string `orm:"size(256);null"` // 路径

	T_State int `orm:"size(2);default(1)"` // 0 删除（伪删除）   1 正常

	Children []InfoTemplateClass `orm:"-"`
}

func (t *InfoTemplateClass) TableName() string {
	return "info_template_class" // 数据库名称   // ************** 替换 FormulaList **************
}

func init() {
	//注册模型
	orm.RegisterModel(new(InfoTemplateClass))
}

type InfoTemplateClass_R struct {
	Id       int
	T_fid    int                 // 项目 id， InfoTemplateClass.ID
	T_name   string              // 名称
	T_State  int                 // 0 删除（伪删除）   1 正常（已交付）     2 开发中
	Children []InfoTemplateClass `orm:"-"`
}

func Read_InfoTemplateClass_List_ALL() (maps []InfoTemplateClass) {

	o := orm.NewOrm()
	qs := o.QueryTable(new(InfoTemplateClass))

	qs.OrderBy("Id").All(&maps)
	return maps
}
func InfoTemplateClassListToMap(A []InfoTemplateClass) map[string]string {
	maps := make(map[string]string, len(A))
	for _, v := range A {
		maps[strconv.Itoa(v.Id)] = v.T_name
	}
	return maps
}

// 获取 ById
func Read_InfoTemplateClass_ById(id int) (r InfoTemplateClass, err error) {
	o := orm.NewOrm()
	r = InfoTemplateClass{Id: id, T_State: 1}
	err = o.Read(&r, "Id", "T_State")
	if err != nil {
		logs.Error(lib.FuncName(), err)
		return r, err
	}
	return r, err
}

// 添加
func Add_InfoTemplateClass(var_ InfoTemplateClass) (id int64, err error) {
	o := orm.NewOrm()
	o.Begin()
	id, err = o.Insert(&var_)
	if err != nil {
		o.Rollback()
		return id, err
	}

	T_Path := "/0/" + strconv.Itoa(int(id)) + "/"
	if var_.T_fid != 0 {
		class_r, err := Read_InfoTemplateClass_ById(var_.T_fid)
		if err != nil {
			o.Rollback()
			return id, err
		}
		T_Path = class_r.T_path + strconv.Itoa(int(id)) + "/"
	}

	var_.Id = int(id)
	var_.T_path = T_Path
	_, err = o.Update(&var_, "T_path")
	if err != nil {
		o.Rollback()
		return id, err
	}
	o.Commit()

	return id, err
}

// 修改
func Update_InfoTemplateClass(r InfoTemplateClass, cols ...string) bool {
	o := orm.NewOrm()
	if num, err := o.Update(&r, cols...); err == nil {
		logs.Println("Number of records updated in database:", num)
		return true
	}
	return false
}

// 批量删除
func Delete_InfoTemplateClass_ByIds(ids []int) bool {
	o := orm.NewOrm()
	o.Begin()
	for _, id := range ids {
		v := InfoTemplateClass{Id: id, T_State: 0}
		if _, err := o.Update(&v, "T_State"); err != nil {
			o.Rollback()
			return false
		}
	}

	o.Commit()
	return true
}

// 获取列表
func Read_InfoTemplateClass_List() (r []InfoTemplateClass) {

	o := orm.NewOrm()
	// 也可以直接使用 Model 结构体作为表名
	var map_r []InfoTemplateClass
	qs := o.QueryTable(new(InfoTemplateClass))

	cond := orm.NewCondition()

	cond1 := cond.And("T_State", 1)

	qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)

	r = InfoTemplateClass_Call(map_r, 0)

	return r

}

func InfoTemplateClass_Call(list []InfoTemplateClass, parentId int) []InfoTemplateClass {
	res := make([]InfoTemplateClass, 0)
	for _, v := range list {
		if v.T_fid == parentId {
			v.Children = InfoTemplateClass_Call(list, v.Id)
			res = append(res, v)
		}
	}
	return res
}

// 通过T_pid查询所有子id
func ReadInfoTemplateClassIds_T_path(T_path string) (InfoTemplateClassIds []int) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(InfoTemplateClass))
	var InfoTemplateClassList []InfoTemplateClass
	qs.Filter("T_path__startswith", T_path).Filter("T_State", 1).All(&InfoTemplateClassList)
	for _, v := range InfoTemplateClassList {
		InfoTemplateClassIds = append(InfoTemplateClassIds, v.Id)
	}
	return InfoTemplateClassIds
}

// 通过T_path查询所有子信息采集分类
func ReadInfoTemplateClassList_T_path(T_path string, parentId int) (r []InfoTemplateClass) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(InfoTemplateClass))
	var InfoTemplateClassList []InfoTemplateClass
	qs.Filter("T_path__startswith", T_path).Filter("T_State", 1).All(&InfoTemplateClassList)
	r = InfoTemplateClass_Call(InfoTemplateClassList, parentId)
	return r
}

// 递归复制节点
func copyInfoTemplateClass(o orm.Ormer, r *InfoTemplateClass, newParentId int, parentPath string) (*InfoTemplateClass, error) {

	// 创建新节点
	infoTemplateClass := InfoTemplateClass{
		T_fid:   newParentId,
		T_name:  r.T_name, // 添加副本标识
		T_State: 1,
		// T_path 将在插入后更新
	}

	// 插入数据库
	newInfoTemplateClassId, err := o.Insert(&infoTemplateClass)
	if err != nil {
		return nil, err
	}

	newPath := parentPath + strconv.Itoa(infoTemplateClass.Id) + "/"

	// 更新路径
	infoTemplateClass.Id = int(newInfoTemplateClassId)
	infoTemplateClass.T_path = newPath
	_, err = o.Update(&infoTemplateClass, "T_path")
	if err != nil {
		return nil, err
	}

	// 复制子节点
	for _, child := range r.Children {
		_, err = copyInfoTemplateClass(o, &child, infoTemplateClass.Id, newPath)
		if err != nil {
			return nil, err
		}
	}
	// 分类1
	//  ----模版
	//	--------标签
	// 分类2
	//   -- 子分类
	// 2 复制分类下的模版
	// 3 复制模版下的标签
	infoTemplateList, _ := Read_InfoTemplate_List(r.Id, "", 0, 9999)
	for _, v := range infoTemplateList {
		infoTemplate, is := Read_InfoTemplate(v.T_InfoTemplate_id)
		if !is {
			return nil, errors.New("查询信息采集模版失败")
		}

		newInfoTemplate := InfoTemplate{
			T_class: infoTemplateClass.Id, // 新的分类id
			T_name:  infoTemplate.T_name,
			T_sort:  infoTemplate.T_sort,
		}

		newInfoTemplateId, is := Add_InfoTemplate(newInfoTemplate)
		if !is {
			return nil, errors.New("复制信息采集模版失败")
		}

		// 复制模版下面的标签
		mapList, _ := Read_InfoTemplateMap_List(v.T_InfoTemplate_id, 0, 0)
		tempMap := make(map[string]struct{})
		idList := make([]string, len(mapList))
		// 生成mapList长度的T_id
		for i := 0; i < len(mapList); i++ {
			// 生成编号
			rand_x := 0
			T_id := ""
			for rand_x < 100 {
				T_id = lib.GetRandstring(4, "", int64(rand_x))
				_, is = Read_InfoTemplateMap(T_id)
				if !is {
					if _, ok := tempMap[T_id]; !ok {
						break
					}
				}
				rand_x += 1
			}
			tempMap[T_id] = struct{}{}
			idList[i] = T_id
		}
		mapInsertList := make([]InfoTemplateMap, 0)
		for i, m := range mapList {
			vtm := InfoTemplateMap{
				T_id:              idList[i],
				T_InfoTemplate_id: newInfoTemplateId,
				T_name:            m.T_name,
				T_text:            m.T_text,
				T_label:           m.T_label,
				T_sort:            m.T_sort,
			}

			mapInsertList = append(mapInsertList, vtm)
		}

		_, is = Add_InfoTemplateMapMulti(mapInsertList)
		if !is {
			return nil, errors.New("复制信息采集模版标签失败")
		}
	}

	return &infoTemplateClass, nil
}

func CopyInfoTemplateClassTree(T_path string, parentId int, T_name string) (newRoot *InfoTemplateClass, err error) {
	// 获取原始节点及其子树
	o := orm.NewOrm()
	srcNode := ReadInfoTemplateClassList_T_path(T_path, parentId)

	if len(srcNode) == 0 {
		return nil, errors.New("查询信息采集分类失败")
	}
	srcNode[0].T_name = T_name
	// 开启事务
	err = o.Begin()
	if err != nil {
		o.Rollback()
		return nil, fmt.Errorf("事务启动失败: %v", err)
	}

	s := strings.Split(strings.Trim(T_path, "/"), "/")
	parentPath := fmt.Sprintf("/%s/", strings.Join(s[:len(s)-1], "/"))
	// 递归复制
	newRoot, err = copyInfoTemplateClass(o, &srcNode[0], parentId, parentPath) // 假设复制到根目录
	if err != nil {
		o.Rollback()
		return nil, err
	}

	// 提交事务
	if err = o.Commit(); err != nil {
		o.Rollback()
		return nil, fmt.Errorf("事务提交失败: %v", err)
	}

	return newRoot, nil
}
