package httpapi

import (
	"net/http"
	"strings"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
	"github.com/google/uuid"
)

// listAdminTasks godoc
// @Summary 管理员列出任务
// @Description 跨租户分页查询任务；请求、结果和执行快照中的常见敏感字段默认脱敏。
// @Tags admin-tasks
// @Produce json
// @Security BearerAuth
// @Param q query string false "关键词，匹配任务、用户、租户、模型、平台和 API Key"
// @Param tenantId query string false "网关租户 ID"
// @Param userId query string false "网关用户 ID"
// @Param userGroupId query string false "用户组 ID"
// @Param status query string false "任务状态"
// @Param platformId query string false "执行平台 ID"
// @Param model query string false "调用或实际模型名称"
// @Param modelType query string false "模型类型"
// @Param runMode query string false "运行模式"
// @Param billingStatus query string false "计费状态"
// @Param apiKey query string false "API Key ID、名称或前缀"
// @Param createdFrom query string false "创建时间起点，支持 RFC3339 或日期格式"
// @Param createdTo query string false "创建时间终点，支持 RFC3339 或日期格式"
// @Param page query int false "页码" default(1)
// @Param pageSize query int false "每页数量" default(50)
// @Success 200 {object} AdminTaskListResponse
// @Failure 400 {object} ErrorEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 500 {object} ErrorEnvelope
// @Router /api/admin/tasks [get]
func (s *Server) listAdminTasks(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	page, err := positiveQueryInt(query.Get("page"), 1)
	if err != nil {
		writeError(w, http.StatusBadRequest, "invalid page")
		return
	}
	pageSize, err := positiveQueryInt(query.Get("pageSize"), 50)
	if err != nil {
		writeError(w, http.StatusBadRequest, "invalid pageSize")
		return
	}
	createdFrom, err := parseTaskListTime(query.Get("createdFrom"), query.Get("from"))
	if err != nil {
		writeError(w, http.StatusBadRequest, "invalid createdFrom")
		return
	}
	createdTo, err := parseTaskListTime(query.Get("createdTo"), query.Get("to"))
	if err != nil {
		writeError(w, http.StatusBadRequest, "invalid createdTo")
		return
	}
	for name, value := range map[string]string{
		"tenantId":    query.Get("tenantId"),
		"userId":      query.Get("userId"),
		"userGroupId": query.Get("userGroupId"),
		"platformId":  query.Get("platformId"),
	} {
		if value != "" && !validUUID(value) {
			writeError(w, http.StatusBadRequest, "invalid "+name)
			return
		}
	}

	result, err := s.store.ListAdminTasks(r.Context(), store.AdminTaskListFilter{
		Query:         firstNonEmpty(query.Get("q"), query.Get("query")),
		GatewayTenant: query.Get("tenantId"),
		GatewayUser:   query.Get("userId"),
		UserGroup:     query.Get("userGroupId"),
		Status:        query.Get("status"),
		Platform:      query.Get("platformId"),
		Model:         query.Get("model"),
		ModelType:     query.Get("modelType"),
		RunMode:       query.Get("runMode"),
		BillingStatus: query.Get("billingStatus"),
		APIKey:        query.Get("apiKey"),
		CreatedFrom:   createdFrom,
		CreatedTo:     createdTo,
		Page:          page,
		PageSize:      pageSize,
	})
	if err != nil {
		s.logger.Error("list admin tasks failed", "error", err)
		writeError(w, http.StatusInternalServerError, "list admin tasks failed")
		return
	}
	for index := range result.Items {
		result.Items[index] = store.MaskAdminGatewayTask(result.Items[index])
	}
	writeJSON(w, http.StatusOK, map[string]any{
		"items":    result.Items,
		"total":    result.Total,
		"page":     result.Page,
		"pageSize": result.PageSize,
	})
}

// getAdminTask godoc
// @Summary 管理员获取任务详情
// @Description 返回任意租户的任务详情；默认脱敏，sensitive=full 时返回完整存储内容。
// @Tags admin-tasks
// @Produce json
// @Security BearerAuth
// @Param taskID path string true "任务 ID"
// @Param sensitive query string false "敏感字段模式" Enums(masked,full) default(masked)
// @Success 200 {object} store.AdminGatewayTask
// @Failure 400 {object} ErrorEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 500 {object} ErrorEnvelope
// @Router /api/admin/tasks/{taskID} [get]
func (s *Server) getAdminTask(w http.ResponseWriter, r *http.Request) {
	taskID := r.PathValue("taskID")
	if !validUUID(taskID) {
		writeError(w, http.StatusBadRequest, "invalid taskID")
		return
	}
	full, ok := parseAdminTaskSensitiveMode(r.URL.Query().Get("sensitive"))
	if !ok {
		writeError(w, http.StatusBadRequest, "invalid sensitive mode")
		return
	}
	task, err := s.store.GetAdminTask(r.Context(), taskID)
	if err != nil {
		if store.IsNotFound(err) {
			writeError(w, http.StatusNotFound, "task not found")
			return
		}
		s.logger.Error("get admin task failed", "taskID", taskID, "error", err)
		writeError(w, http.StatusInternalServerError, "get admin task failed")
		return
	}
	task.GatewayTask, err = s.hydrateTaskResult(r.Context(), task.GatewayTask)
	if err != nil {
		writeStoredBinaryResultError(w, err)
		return
	}
	if !full {
		task = store.MaskAdminGatewayTask(task)
	}
	writeJSON(w, http.StatusOK, task)
}

// adminTaskParamPreprocessing godoc
// @Summary 管理员获取任务参数预处理日志
// @Description 返回任意租户任务的参数改写、校验或模板处理日志；默认脱敏。
// @Tags admin-tasks
// @Produce json
// @Security BearerAuth
// @Param taskID path string true "任务 ID"
// @Param sensitive query string false "敏感字段模式" Enums(masked,full) default(masked)
// @Success 200 {object} TaskParamPreprocessingLogListResponse
// @Failure 400 {object} ErrorEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 500 {object} ErrorEnvelope
// @Router /api/admin/tasks/{taskID}/param-preprocessing [get]
func (s *Server) adminTaskParamPreprocessing(w http.ResponseWriter, r *http.Request) {
	taskID := r.PathValue("taskID")
	if !validUUID(taskID) {
		writeError(w, http.StatusBadRequest, "invalid taskID")
		return
	}
	full, ok := parseAdminTaskSensitiveMode(r.URL.Query().Get("sensitive"))
	if !ok {
		writeError(w, http.StatusBadRequest, "invalid sensitive mode")
		return
	}
	if _, err := s.store.GetAdminTask(r.Context(), taskID); err != nil {
		if store.IsNotFound(err) {
			writeError(w, http.StatusNotFound, "task not found")
			return
		}
		s.logger.Error("get admin task failed", "taskID", taskID, "error", err)
		writeError(w, http.StatusInternalServerError, "get admin task failed")
		return
	}
	items, err := s.store.ListTaskParamPreprocessingLogs(r.Context(), taskID)
	if err != nil {
		s.logger.Error("list admin task parameter preprocessing logs failed", "taskID", taskID, "error", err)
		writeError(w, http.StatusInternalServerError, "list admin task parameter preprocessing logs failed")
		return
	}
	if !full {
		items = store.MaskTaskParamPreprocessingLogs(items)
	}
	writeJSON(w, http.StatusOK, map[string]any{"items": items})
}

func parseAdminTaskSensitiveMode(value string) (bool, bool) {
	switch strings.ToLower(strings.TrimSpace(value)) {
	case "", "masked":
		return false, true
	case "full":
		return true, true
	default:
		return false, false
	}
}

func validUUID(value string) bool {
	_, err := uuid.Parse(strings.TrimSpace(value))
	return err == nil
}
