package system

import (
	"kra/internal/biz/system"
	"kra/internal/server/middleware"
	types "kra/internal/service/types/system"

	"github.com/go-kratos/kratos/v2/errors"
	khttp "github.com/go-kratos/kratos/v2/transport/http"
)

// ApiService API服务
type ApiService struct {
	uc *system.ApiUsecase
}

// NewApiService 创建API服务
func NewApiService(uc *system.ApiUsecase) *ApiService {
	return &ApiService{uc: uc}
}

// CreateApi 创建API
func (s *ApiService) CreateApi(ctx khttp.Context) error {
	var req types.CreateApiRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	api := &system.Api{
		Path:        req.Path,
		Description: req.Description,
		ApiGroup:    req.ApiGroup,
		Method:      req.Method,
	}
	if err := s.uc.CreateApi(ctx, api); err != nil {
		return errors.BadRequest("CREATE_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// UpdateApi 更新API
func (s *ApiService) UpdateApi(ctx khttp.Context) error {
	var req types.UpdateApiRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	api := &system.Api{
		ID:          req.ID,
		Path:        req.Path,
		Description: req.Description,
		ApiGroup:    req.ApiGroup,
		Method:      req.Method,
	}
	if err := s.uc.UpdateApi(ctx, api); err != nil {
		return errors.BadRequest("UPDATE_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// DeleteApi 删除API
func (s *ApiService) DeleteApi(ctx khttp.Context) error {
	var req types.DeleteApiRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.uc.DeleteApi(ctx, req.ID); err != nil {
		return errors.BadRequest("DELETE_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// DeleteApisByIds 批量删除API
func (s *ApiService) DeleteApisByIds(ctx khttp.Context) error {
	var req types.DeleteApisByIdsRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.uc.DeleteApisByIds(ctx, req.Ids); err != nil {
		return errors.BadRequest("DELETE_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// GetApiById 根据ID获取API
func (s *ApiService) GetApiById(ctx khttp.Context) error {
	var req types.GetApiByIdRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	api, err := s.uc.GetApiById(ctx, req.ID)
	if err != nil {
		return errors.NotFound("NOT_FOUND", err.Error())
	}
	return ctx.Result(200, &types.GetApiByIdReply{Api: toTypesApiInfo(api)})
}

// GetApiList 获取API列表
func (s *ApiService) GetApiList(ctx khttp.Context) error {
	var req types.GetApiListRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	filters := make(map[string]string)
	if req.Path != "" {
		filters["path"] = req.Path
	}
	if req.Description != "" {
		filters["description"] = req.Description
	}
	if req.Method != "" {
		filters["method"] = req.Method
	}
	if req.ApiGroup != "" {
		filters["api_group"] = req.ApiGroup
	}
	apis, total, err := s.uc.GetAPIInfoList(ctx, req.Page, req.PageSize, filters, req.OrderKey, req.Desc)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	list := make([]types.ApiInfo, len(apis))
	for i, api := range apis {
		list[i] = toTypesApiInfo(api)
	}
	return ctx.Result(200, &types.GetApiListReply{List: list, Total: total, Page: req.Page, PageSize: req.PageSize})
}

// GetAllApis 获取所有API
func (s *ApiService) GetAllApis(ctx khttp.Context) error {
	authorityID := middleware.GetAuthorityID(ctx)
	apis, err := s.uc.GetAllApis(ctx, authorityID)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	list := make([]types.ApiInfo, len(apis))
	for i, api := range apis {
		list[i] = toTypesApiInfo(api)
	}
	return ctx.Result(200, &types.GetAllApisReply{Apis: list})
}

// GetApiGroups 获取API分组
func (s *ApiService) GetApiGroups(ctx khttp.Context) error {
	groups, apiGroupMap, err := s.uc.GetApiGroups(ctx)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	return ctx.Result(200, &types.GetApiGroupsReply{Groups: groups, ApiGroupMap: apiGroupMap})
}

// SyncApi 同步API
func (s *ApiService) SyncApi(ctx khttp.Context) error {
	newApis, deleteApis, ignoreApis, err := s.uc.SyncApi(ctx)
	if err != nil {
		return errors.InternalServer("SYNC_ERROR", err.Error())
	}
	return ctx.Result(200, &types.SyncApiReply{
		NewApis:    toTypesApiInfoList(newApis),
		DeleteApis: toTypesApiInfoList(deleteApis),
		IgnoreApis: toTypesApiInfoList(ignoreApis),
	})
}

// IgnoreApi 忽略API
func (s *ApiService) IgnoreApi(ctx khttp.Context) error {
	var req types.IgnoreApiRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.uc.IgnoreApi(ctx, req.Path, req.Method, req.Flag); err != nil {
		return errors.BadRequest("IGNORE_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// EnterSyncApi 确认同步API
func (s *ApiService) EnterSyncApi(ctx khttp.Context) error {
	var req types.EnterSyncApiRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	newApis := make([]*system.Api, len(req.NewApis))
	for i, api := range req.NewApis {
		newApis[i] = &system.Api{
			Path:        api.Path,
			Description: api.Description,
			ApiGroup:    api.ApiGroup,
			Method:      api.Method,
		}
	}
	deleteApis := make([]*system.Api, len(req.DeleteApis))
	for i, api := range req.DeleteApis {
		deleteApis[i] = &system.Api{
			ID:     api.ID,
			Path:   api.Path,
			Method: api.Method,
		}
	}
	if err := s.uc.EnterSyncApi(ctx, newApis, deleteApis); err != nil {
		return errors.BadRequest("SYNC_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// FreshCasbin 刷新Casbin缓存
func (s *ApiService) FreshCasbin(ctx khttp.Context) error {
	if err := s.uc.FreshCasbin(); err != nil {
		return errors.InternalServer("FRESH_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// toTypesApiInfo 转换API信息为types格式
func toTypesApiInfo(api *system.Api) types.ApiInfo {
	if api == nil {
		return types.ApiInfo{}
	}
	return types.ApiInfo{
		ID:          api.ID,
		Path:        api.Path,
		Description: api.Description,
		ApiGroup:    api.ApiGroup,
		Method:      api.Method,
	}
}

// toTypesApiInfoList 批量转换API信息
func toTypesApiInfoList(apis []*system.Api) []types.ApiInfo {
	list := make([]types.ApiInfo, len(apis))
	for i, api := range apis {
		list[i] = toTypesApiInfo(api)
	}
	return list
}

// RegisterRoutes 注册API管理路由
func (s *ApiService) RegisterRoutes(rg *RouterGroup) {
	// 公开路由
	rg.Public.GET("/api/freshCasbin", s.FreshCasbin)

	// 私有路由 + 操作记录（写操作）
	rg.PrivateWithRecord.GET("/api/getApiGroups", s.GetApiGroups)
	rg.PrivateWithRecord.GET("/api/syncApi", s.SyncApi)
	rg.PrivateWithRecord.POST("/api/ignoreApi", s.IgnoreApi)
	rg.PrivateWithRecord.POST("/api/enterSyncApi", s.EnterSyncApi)
	rg.PrivateWithRecord.POST("/api/createApi", s.CreateApi)
	rg.PrivateWithRecord.POST("/api/deleteApi", s.DeleteApi)
	rg.PrivateWithRecord.POST("/api/getApiById", s.GetApiById)
	rg.PrivateWithRecord.POST("/api/updateApi", s.UpdateApi)
	rg.PrivateWithRecord.DELETE("/api/deleteApisByIds", s.DeleteApisByIds)

	// 私有路由（读操作，不记录）
	rg.Private.POST("/api/getAllApis", s.GetAllApis)
	rg.Private.POST("/api/getApiList", s.GetApiList)
}
