package system

import (
	"fmt"

	"kra/internal/biz/system"
	types "kra/internal/service/types/system"

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

// OperationRecordService 操作记录服务
type OperationRecordService struct {
	uc *system.OperationRecordUsecase
}

// NewOperationRecordService 创建操作记录服务
func NewOperationRecordService(uc *system.OperationRecordUsecase) *OperationRecordService {
	return &OperationRecordService{uc: uc}
}

// OperationRecordInfo 操作记录信息
type OperationRecordInfo struct {
	ID           uint            `json:"id"`
	IP           string          `json:"ip"`
	Method       string          `json:"method"`
	Path         string          `json:"path"`
	Status       int             `json:"status"`
	Latency      int64           `json:"latency"`
	Agent        string          `json:"agent"`
	ErrorMessage string          `json:"error_message"`
	Body         string          `json:"body"`
	Resp         string          `json:"resp"`
	UserID       uint            `json:"user_id"`
	User         *types.UserInfo `json:"user,omitempty"`
}

// GetOperationRecordListRequest 获取操作记录列表请求
type GetOperationRecordListRequest struct {
	Page     int    `json:"page"`
	PageSize int    `json:"pageSize"`
	Method   string `json:"method"`
	Path     string `json:"path"`
	Status   int    `json:"status"`
	UserID   uint   `json:"user_id"`
}

// GetOperationRecordListResponse 获取操作记录列表响应
type GetOperationRecordListResponse struct {
	List     []*OperationRecordInfo `json:"list"`
	Total    int64                  `json:"total"`
	Page     int                    `json:"page"`
	PageSize int                    `json:"pageSize"`
}

// DeleteOperationRecordRequest 删除操作记录请求
type DeleteOperationRecordRequest struct {
	ID uint `json:"id"`
}

// DeleteOperationRecordByIdsRequest 批量删除操作记录请求
type DeleteOperationRecordByIdsRequest struct {
	IDs []uint `json:"ids"`
}

// RegisterRoutes 注册路由
func (s *OperationRecordService) RegisterRoutes(rg *RouterGroup) {
	// 操作记录（不需要操作记录中间件，避免递归）
	rg.Private.DELETE("/sysOperationRecord/deleteSysOperationRecord", s.handleDelete)
	rg.Private.DELETE("/sysOperationRecord/deleteSysOperationRecordByIds", s.handleDeleteByIds)
	rg.Private.GET("/sysOperationRecord/findSysOperationRecord", s.handleFind)
	rg.Private.GET("/sysOperationRecord/getSysOperationRecordList", s.handleGetList)
}

func (s *OperationRecordService) handleGetList(ctx http.Context) error {
	var req GetOperationRecordListRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	filters := make(map[string]interface{})
	if req.Method != "" {
		filters["method"] = req.Method
	}
	if req.Path != "" {
		filters["path"] = req.Path
	}
	if req.Status != 0 {
		filters["status"] = req.Status
	}
	if req.UserID != 0 {
		filters["user_id"] = req.UserID
	}
	list, total, err := s.uc.GetOperationRecordList(ctx, req.Page, req.PageSize, filters)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	resp := &GetOperationRecordListResponse{
		List:     make([]*OperationRecordInfo, len(list)),
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}
	for i, r := range list {
		resp.List[i] = toOperationRecordInfo(r)
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": resp})
}

func (s *OperationRecordService) handleDelete(ctx http.Context) error {
	var req DeleteOperationRecordRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.uc.DeleteOperationRecord(ctx, req.ID); err != nil {
		return errors.InternalServer("DELETE_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "删除成功"})
}

func (s *OperationRecordService) handleDeleteByIds(ctx http.Context) error {
	var req DeleteOperationRecordByIdsRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.uc.DeleteOperationRecordByIds(ctx, req.IDs); err != nil {
		return errors.InternalServer("DELETE_ERROR", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "批量删除成功"})
}

func (s *OperationRecordService) handleFind(ctx http.Context) error {
	idStr := ctx.Request().URL.Query().Get("id")
	if idStr == "" {
		return errors.BadRequest("INVALID_ID", "id参数不能为空")
	}
	var id uint
	if _, err := fmt.Sscanf(idStr, "%d", &id); err != nil {
		return errors.BadRequest("INVALID_ID", "id参数格式错误")
	}
	record, err := s.uc.GetOperationRecord(ctx, id)
	if err != nil {
		return errors.NotFound("NOT_FOUND", err.Error())
	}
	return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": toOperationRecordInfo(record)})
}

func toOperationRecordInfo(r *system.OperationRecord) *OperationRecordInfo {
	info := &OperationRecordInfo{
		ID:           r.ID,
		IP:           r.IP,
		Method:       r.Method,
		Path:         r.Path,
		Status:       r.Status,
		Latency:      r.Latency,
		Agent:        r.Agent,
		ErrorMessage: r.ErrorMessage,
		Body:         r.Body,
		Resp:         r.Resp,
		UserID:       r.UserID,
	}
	if r.User != nil {
		userInfo := toTypesUserInfo(r.User)
		info.User = &userInfo
	}
	return info
}
