package handler

import (
	"kra/internal/service"
	"kra/internal/service/dto"

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

type API struct{ service *service.APIService }

func NewAPI(service *service.APIService) *API { return &API{service: service} }

func (h *API) List(c *gin.Context) {
	var req dto.APIListRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.Page == 0 {
		Fail(c, "Page值不能为空")
		return
	}
	if req.PageSize == 0 {
		Fail(c, "PageSize值不能为空")
		return
	}
	items, total, err := h.service.ListAPI(c.Request.Context(), &req)
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, PageResult{List: items, Total: total, Page: req.Page, PageSize: req.PageSize}, "获取成功")
}
func (h *API) All(c *gin.Context) {
	items, err := h.service.AllAPI(c.Request.Context(), true)
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, gin.H{"apis": items}, "获取成功")
}
func (h *API) Create(c *gin.Context) {
	var req dto.APIRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if message := validateAPIRequest(&req); message != "" {
		Fail(c, message)
		return
	}
	created, err := h.service.CreateAPIRequest(c.Request.Context(), &req)
	if err != nil {
		Fail(c, "创建失败")
		return
	}
	Write(c, CodeSuccess, created, "创建成功")
}
func (h *API) Update(c *gin.Context) {
	var req dto.APIRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if message := validateAPIRequest(&req); message != "" {
		Fail(c, message)
		return
	}
	if err := h.service.UpdateAPIRequest(c.Request.Context(), &req); err != nil {
		Fail(c, "修改失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "修改成功")
}
func (h *API) Delete(c *gin.Context) {
	var req dto.DeleteAPIRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.ID == 0 {
		Fail(c, "ID值不能为空")
		return
	}
	if err := h.service.DeleteAPI(c.Request.Context(), req.ID); err != nil {
		Fail(c, "删除失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "删除成功")
}
func (h *API) DeleteByIDs(c *gin.Context) {
	var req dto.DeleteAPIsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.DeleteAPIs(c.Request.Context(), req.IDs); err != nil {
		Fail(c, "删除失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "删除成功")
}
func (h *API) Find(c *gin.Context) {
	var req dto.GetAPIRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.ID == 0 {
		Fail(c, "ID值不能为空")
		return
	}
	item, err := h.service.FindAPIResponse(c.Request.Context(), req.ID)
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, gin.H{"api": item}, "获取成功")
}
func (h *API) Groups(c *gin.Context) {
	groups, groupAPIMap, err := h.service.Groups(c.Request.Context())
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	OKWithData(c, gin.H{"groups": groups, "apiGroupMap": groupAPIMap})
}
func (h *API) Roles(c *gin.Context) {
	path, method := c.Query("path"), c.Query("method")
	if path == "" || method == "" {
		Fail(c, "API路径和请求方法不能为空")
		return
	}
	ids, err := h.service.APIRoleIDs(c.Request.Context(), path, method)
	if err != nil {
		Fail(c, "获取失败"+err.Error())
		return
	}
	if ids == nil {
		ids = []uint{}
	}
	Write(c, CodeSuccess, ids, "获取成功")
}
func (h *API) SetRoles(c *gin.Context) {
	var req dto.SetAPIRolesRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.Path == "" || req.Method == "" {
		Fail(c, "API路径和请求方法不能为空")
		return
	}
	if err := h.service.SetAPIRoles(c.Request.Context(), req.Path, req.Method, req.AuthorityIDs); err != nil {
		Fail(c, "设置失败"+err.Error())
		return
	}
	Write(c, CodeSuccess, gin.H{}, "设置成功")
}
func (h *API) Sync(engine *gin.Engine) gin.HandlerFunc {
	return func(c *gin.Context) {
		routes := engine.Routes()
		values := make([]dto.APIRequest, 0, len(routes))
		for _, route := range routes {
			values = append(values, dto.APIRequest{Path: route.Path, Method: route.Method})
		}
		result, err := h.service.SyncAPIResponses(c.Request.Context(), values)
		if err != nil {
			Fail(c, "同步失败")
			return
		}
		OKWithData(c, result)
	}
}
func (h *API) Ignore(c *gin.Context) {
	var req dto.IgnoreAPIRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.SetAPIIgnored(c.Request.Context(), req.Path, req.Method, req.Flag); err != nil {
		Fail(c, "忽略失败")
		return
	}
	OK(c)
}
func (h *API) ApplySync(c *gin.Context) {
	var req dto.ApplyAPISyncRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if err := h.service.ApplyAPISyncRequest(c.Request.Context(), &req); err != nil {
		Fail(c, "忽略失败")
		return
	}
	OK(c)
}
func (h *API) FreshCasbin(c *gin.Context) {
	if err := h.service.FreshCasbin(c.Request.Context()); err != nil {
		Fail(c, "刷新失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "刷新成功")
}

func (h *API) SetPolicyPaths(c *gin.Context) {
	var req dto.SetPolicyPathsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.AuthorityID == 0 {
		Fail(c, "AuthorityId值不能为空")
		return
	}
	if err := h.service.SetPolicyPathsRequest(c.Request.Context(), &req); err != nil {
		Fail(c, "更新失败")
		return
	}
	Write(c, CodeSuccess, gin.H{}, "更新成功")
}
func (h *API) PolicyPaths(c *gin.Context) {
	var req dto.GetPolicyPathsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err.Error())
		return
	}
	if req.AuthorityID == 0 {
		Fail(c, "AuthorityId值不能为空")
		return
	}
	paths, err := h.service.PolicyPathResponses(c.Request.Context(), req.AuthorityID)
	if err != nil {
		Fail(c, "获取失败")
		return
	}
	Write(c, CodeSuccess, gin.H{"paths": paths}, "获取成功")
}

func validateAPIRequest(req *dto.APIRequest) string {
	switch {
	case req.Path == "":
		return "Path值不能为空"
	case req.Description == "":
		return "Description值不能为空"
	case req.APIGroup == "":
		return "ApiGroup值不能为空"
	case req.Method == "":
		return "Method值不能为空"
	default:
		return ""
	}
}
