package system

import (
	"kra/internal/biz/system"
	"kra/pkg/response"
	"kra/pkg/utils"

	"github.com/gin-gonic/gin"
)

type MenuApi struct{}

// AddBaseMenuRequest 添加菜单请求
type AddBaseMenuRequest struct {
	ParentId   uint                   `json:"parentId"`
	Path       string                 `json:"path" binding:"required"`
	Name       string                 `json:"name" binding:"required"`
	Hidden     bool                   `json:"hidden"`
	Component  string                 `json:"component"`
	Sort       int                    `json:"sort"`
	Meta       map[string]interface{} `json:"meta"`
	Parameters []MenuParameter        `json:"parameters"`
	MenuBtn    []MenuBtn              `json:"menuBtn"`
}

// MenuParameter 菜单参数
type MenuParameter struct {
	Type  string `json:"type"`
	Key   string `json:"key"`
	Value string `json:"value"`
}

// MenuBtn 菜单按钮
type MenuBtn struct {
	Name string `json:"name"`
	Desc string `json:"desc"`
}

// UpdateBaseMenuRequest 更新菜单请求
type UpdateBaseMenuRequest struct {
	ID         uint                   `json:"ID" binding:"required"`
	ParentId   uint                   `json:"parentId"`
	Path       string                 `json:"path" binding:"required"`
	Name       string                 `json:"name" binding:"required"`
	Hidden     bool                   `json:"hidden"`
	Component  string                 `json:"component"`
	Sort       int                    `json:"sort"`
	Meta       map[string]interface{} `json:"meta"`
	Parameters []MenuParameter        `json:"parameters"`
	MenuBtn    []MenuBtn              `json:"menuBtn"`
}

// DeleteBaseMenuRequest 删除菜单请求
type DeleteBaseMenuRequest struct {
	ID uint `json:"ID" binding:"required"`
}

// GetMenuByIdRequest 根据ID获取菜单请求
type GetMenuByIdRequest struct {
	ID uint `json:"ID" binding:"required"`
}

// AddMenuAuthorityRequest 添加菜单权限请求
type AddMenuAuthorityRequest struct {
	AuthorityId uint   `json:"authorityId" binding:"required"`
	Menus       []uint `json:"menus"`
}

// GetMenuAuthorityRequest 获取菜单权限请求
type GetMenuAuthorityRequest struct {
	AuthorityId uint `json:"authorityId" binding:"required"`
}

// AddBaseMenu
// @Tags      Menu
// @Summary   新增菜单
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      AddBaseMenuRequest             true  "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success   200   {object}  response.Response{msg=string}  "新增菜单"
// @Router    /menu/addBaseMenu [post]
func (m *MenuApi) AddBaseMenu(c *gin.Context) {
	var req AddBaseMenuRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	menu := &system.BaseMenu{
		ParentId:  req.ParentId,
		Path:      req.Path,
		Name:      req.Name,
		Hidden:    req.Hidden,
		Component: req.Component,
		Sort:      req.Sort,
	}

	if err := menuUsecase.AddBaseMenu(c, menu); err != nil {
		response.FailWithMessage("创建失败: "+err.Error(), c)
		return
	}

	response.OkWithMessage("创建成功", c)
}

// DeleteBaseMenu
// @Tags      Menu
// @Summary   删除菜单
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      DeleteBaseMenuRequest          true  "菜单id"
// @Success   200   {object}  response.Response{msg=string}  "删除菜单"
// @Router    /menu/deleteBaseMenu [post]
func (m *MenuApi) DeleteBaseMenu(c *gin.Context) {
	var req DeleteBaseMenuRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	if err := menuUsecase.DeleteBaseMenu(c, req.ID); err != nil {
		response.FailWithMessage("删除失败: "+err.Error(), c)
		return
	}

	response.OkWithMessage("删除成功", c)
}

// UpdateBaseMenu
// @Tags      Menu
// @Summary   更新菜单
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      UpdateBaseMenuRequest          true  "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success   200   {object}  response.Response{msg=string}  "更新菜单"
// @Router    /menu/updateBaseMenu [post]
func (m *MenuApi) UpdateBaseMenu(c *gin.Context) {
	var req UpdateBaseMenuRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	menu := &system.BaseMenu{
		ID:        req.ID,
		ParentId:  req.ParentId,
		Path:      req.Path,
		Name:      req.Name,
		Hidden:    req.Hidden,
		Component: req.Component,
		Sort:      req.Sort,
	}

	if err := menuUsecase.UpdateBaseMenu(c, menu); err != nil {
		response.FailWithMessage("更新失败: "+err.Error(), c)
		return
	}

	response.OkWithMessage("更新成功", c)
}

// GetMenu
// @Tags      Menu
// @Summary   获取用户动态路由
// @Security  ApiKeyAuth
// @Produce   application/json
// @Success   200  {object}  response.Response{data=map[string]interface{},msg=string}  "获取用户动态路由,返回包括系统菜单详情列表"
// @Router    /menu/getMenu [post]
func (m *MenuApi) GetMenu(c *gin.Context) {
	authorityId := utils.GetUserAuthorityId(c)
	menus, err := menuUsecase.GetMenuTree(c, authorityId)
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}

	response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
}

// GetMenuList
// @Tags      Menu
// @Summary   分页获取基础menu列表
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Success   200  {object}  response.Response{data=response.PageResult,msg=string}  "分页获取基础menu列表,返回包括列表,总数,页码,每页数量"
// @Router    /menu/getMenuList [post]
func (m *MenuApi) GetMenuList(c *gin.Context) {
	authorityId := utils.GetUserAuthorityId(c)
	menus, err := menuUsecase.GetInfoList(c, authorityId)
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}

	response.OkWithDetailed(gin.H{"list": menus}, "获取成功", c)
}

// GetBaseMenuTree
// @Tags      Menu
// @Summary   获取用户动态路由
// @Security  ApiKeyAuth
// @Produce   application/json
// @Success   200  {object}  response.Response{data=map[string]interface{},msg=string}  "获取用户动态路由,返回包括系统菜单列表"
// @Router    /menu/getBaseMenuTree [post]
func (m *MenuApi) GetBaseMenuTree(c *gin.Context) {
	authorityId := utils.GetUserAuthorityId(c)
	menus, err := menuUsecase.GetBaseMenuTree(c, authorityId)
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}

	response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
}

// GetBaseMenuById
// @Tags      Menu
// @Summary   根据id获取菜单
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      GetMenuByIdRequest                                     true  "菜单id"
// @Success   200   {object}  response.Response{data=system.BaseMenu,msg=string}  "根据id获取菜单,返回包括系统菜单详情"
// @Router    /menu/getBaseMenuById [post]
func (m *MenuApi) GetBaseMenuById(c *gin.Context) {
	var req GetMenuByIdRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	menu, err := menuUsecase.GetBaseMenuById(c, req.ID)
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}

	response.OkWithDetailed(gin.H{"menu": menu}, "获取成功", c)
}

// AddMenuAuthority
// @Tags      Menu
// @Summary   增加menu和角色关联关系
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      AddMenuAuthorityRequest        true  "角色ID"
// @Success   200   {object}  response.Response{msg=string}  "增加menu和角色关联关系"
// @Router    /menu/addMenuAuthority [post]
func (m *MenuApi) AddMenuAuthority(c *gin.Context) {
	var req AddMenuAuthorityRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 获取当前用户的角色ID
	adminAuthorityId := utils.GetUserAuthorityId(c)

	// 构建菜单列表
	var menus []*system.BaseMenu
	for _, menuId := range req.Menus {
		menus = append(menus, &system.BaseMenu{ID: menuId})
	}

	if err := menuUsecase.AddMenuAuthority(c, menus, adminAuthorityId, req.AuthorityId); err != nil {
		response.FailWithMessage("添加失败: "+err.Error(), c)
		return
	}

	response.OkWithMessage("添加成功", c)
}

// GetMenuAuthority
// @Tags      Menu
// @Summary   获取指定角色menu
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      GetMenuAuthorityRequest                                true  "角色ID"
// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "获取指定角色menu"
// @Router    /menu/getMenuAuthority [post]
func (m *MenuApi) GetMenuAuthority(c *gin.Context) {
	var req GetMenuAuthorityRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	menus, err := menuUsecase.GetMenuAuthority(c, req.AuthorityId)
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}

	response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
}
