package system

import (
	"errors"
	"sundynix-go/global"
	"sundynix-go/model/system"

	"gorm.io/gorm"
)

type MenuService struct{}

var MenuServiceApp = new(MenuService)

func (s *MenuService) SaveMenu(menu system.Menu) error {
	//1.根据code和name查询是否存在重名
	if err := global.DB.Where("code = ? or name = ?", menu.Code, menu.Name).First(&system.Menu{}).Error; err == nil {
		return errors.New("菜单已存在")
	}
	return global.DB.Create(&menu).Error
}

func (s *MenuService) UpdateMenu(menu *system.Menu) (err error) {
	var sysMenu system.Menu
	menuMap := map[string]interface{}{
		"Category":   menu.Category,
		"Name":       menu.Name,
		"Title":      menu.Title,
		"Code":       menu.Code,
		"path":       menu.Path,
		"Permission": menu.Permission,
		"Locale":     menu.Locale,
		"Icon":       menu.Icon,
		"Sort":       menu.Sort,
	}
	err = global.DB.Where("id = ?", menu.Id).First(&sysMenu).Error
	if err != nil {
		global.Logger.Debug(err.Error())
		return errors.New("查询菜单失败")
	}
	err = global.DB.Model(&sysMenu).Updates(menuMap).Error
	return err
}

func (s *MenuService) DeleteMenu(id string) (err error) {
	err = global.DB.First(&system.Menu{}, "parent_id = ?", id).Error
	if err == nil {
		return errors.New("请先删除子菜单")
	}
	var menu system.Menu
	err = global.DB.Where("id = ?", id).First(&menu).Error
	if err != nil {
		return errors.New("菜单记录不存在")
	}
	// 同步删除menu表和role-menu表数据
	return global.DB.Transaction(func(tx *gorm.DB) error {
		if err = tx.Where("id = ?", id).Delete(&system.Menu{}).Error; err != nil {
			return err
		}
		if err = tx.Where("menu_id = ?", id).Delete(&system.RoleMenu{}).Error; err != nil {
			return err
		}
		return nil
	})
}

func (s *MenuService) GetMenuById(id string) (menu system.Menu, err error) {
	var m system.Menu
	err = global.DB.Where("id = ?", id).First(&m).Error
	return m, err
}

func (s *MenuService) GetAllMenuTree(category int, parentId string) (menus []*system.Menu, err error) {
	//1,先根据category和parentId获取所有菜单 category默认为0,parentId默认为0
	//2.讲查询出的列表构建为树结构
	var menuList []*system.Menu
	db := global.DB.Model(&system.Menu{})
	if category != 0 {
		db.Where("category = ?", category)
	}
	if parentId != "0" {
		db.Where("parent_id = ?", parentId)
	}
	err = db.Order("sort asc").Find(&menuList).Error
	if err != nil {
		return nil, err
	}
	tree := buildMenuTree(menuList)
	return tree, nil
}

func (s *MenuService) GetUserRoutes(userId string) (menus []*system.Menu, err error) {
	//1.根据userId 查询角色 根据角色查询菜单 去重
	//2.构建树结构
	var roleIds []string
	err = global.DB.Model(&system.UserRole{}).Where("user_id = ?", userId).Pluck("role_id", &roleIds).Error
	var menuIds []string
	err = global.DB.Model(&system.RoleMenu{}).Where("role_id in ?", roleIds).Pluck("menu_id", &menuIds).Error
	var menuList []*system.Menu
	err = global.DB.Model(&system.Menu{}).Where("id in ? and category = 1 ", menuIds).Order("sort asc").Find(&menuList).Error
	return buildMenuTree(menuList), nil
}

func buildMenuTree(list []*system.Menu) []*system.Menu {
	//1.定义一个map
	menuMap := make(map[string]*system.Menu)
	for _, item := range list {
		menuMap[item.Id] = item
	}
	//构建树结构
	var treeList []*system.Menu
	for _, item := range list {
		if item.ParentId == "0" {
			// 如果没有父节点，直接添加到树中
			treeList = append(treeList, item)
		} else {
			if parent, exists := menuMap[item.ParentId]; exists {
				// 如果有父节点，将当前节点添加到父节点的Children中
				parent.Children = append(parent.Children, item)
			} else {
				// 如果没有父节点，将当前节点添加到树中
				treeList = append(treeList, item)
			}
		}
	}
	return treeList
}
