package logic

import (
	"context"

	sysModel "sundynix-micro-go/app/system/model"
	"sundynix-micro-go/app/system/rpc/internal/svc"
	"sundynix-micro-go/app/system/rpc/system"

	"github.com/zeromicro/go-zero/core/logx"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type GetMenusByRoleIdLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetMenusByRoleIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMenusByRoleIdLogic {
	return &GetMenusByRoleIdLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// 获取角色菜单列表
func (l *GetMenusByRoleIdLogic) GetMenusByRoleId(in *system.GetMenusByRoleIdReq) (*system.GetMenusByRoleIdResp, error) {
	// 查询角色菜单关联
	var roleMenus []sysModel.SundynixRoleMenu
	if err := l.svcCtx.DB.Where("role_id = ?", in.RoleId).Find(&roleMenus).Error; err != nil {
		l.Errorf("查询角色菜单失败: %v", err)
		return nil, status.Error(codes.Internal, "查询角色菜单失败")
	}

	if len(roleMenus) == 0 {
		return &system.GetMenusByRoleIdResp{Menus: []*system.MenuInfo{}}, nil
	}

	menuIds := make([]string, 0, len(roleMenus))
	for _, rm := range roleMenus {
		menuIds = append(menuIds, rm.MenuID)
	}

	// 查询菜单信息
	var menus []sysModel.SundynixMenu
	if err := l.svcCtx.DB.Where("id IN ?", menuIds).Order("sort").Find(&menus).Error; err != nil {
		l.Errorf("查询菜单信息失败: %v", err)
		return nil, status.Error(codes.Internal, "查询菜单信息失败")
	}

	// 构建树形结构
	menuMap := make(map[string]*system.MenuInfo)
	var rootMenus []*system.MenuInfo

	for _, m := range menus {
		menuInfo := &system.MenuInfo{
			Id:         m.ID,
			ParentId:   m.ParentID,
			Category:   int32(m.Category),
			Name:       m.Name,
			Title:      m.Title,
			Code:       m.Code,
			Path:       m.Path,
			Permission: m.Permission,
			Locale:     m.Locale,
			Icon:       m.Icon,
			Sort:       int32(m.Sort),
			Children:   []*system.MenuInfo{},
		}
		menuMap[m.ID] = menuInfo
	}

	for _, m := range menus {
		menuInfo := menuMap[m.ID]
		if menuInfo.ParentId == "0" || menuInfo.ParentId == "" {
			rootMenus = append(rootMenus, menuInfo)
		} else {
			if parent, ok := menuMap[menuInfo.ParentId]; ok {
				parent.Children = append(parent.Children, menuInfo)
			} else {
				rootMenus = append(rootMenus, menuInfo)
			}
		}
	}

	return &system.GetMenusByRoleIdResp{Menus: rootMenus}, nil
}
