package agent

import (
	"errors"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/core/domain"
	"github.com/tidbcloud/AgentTeam/internal/store/agent"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
	"github.com/tidbcloud/AgentTeam/internal/store/storeerr"
	"github.com/tidbcloud/AgentTeam/internal/store/taskboard"
	"github.com/tidbcloud/AgentTeam/internal/workspace/owner"
)

// ParseLimit parses a positive integer query parameter with a fallback.
func ParseLimit(raw string, fallback int) (int, error) {
	if strings.TrimSpace(raw) == "" {
		return fallback, nil
	}
	limit, err := strconv.Atoi(raw)
	if err != nil || limit <= 0 {
		return 0, fmt.Errorf("invalid limit")
	}
	return limit, nil
}

// ParseOptionalSeq parses an optional int64 query parameter.
func ParseOptionalSeq(raw string) (*int64, error) {
	if strings.TrimSpace(raw) == "" {
		return nil, nil
	}
	value, err := strconv.ParseInt(raw, 10, 64)
	if err != nil || value < 0 {
		return nil, fmt.Errorf("invalid sequence")
	}
	return &value, nil
}

func normalizeCommaQueryValues(values []string, extra string) []string {
	if len(values) == 0 && strings.TrimSpace(extra) != "" {
		values = append(values, extra)
	}
	out := make([]string, 0, len(values))
	for _, value := range values {
		for _, part := range strings.Split(value, ",") {
			if trimmed := strings.TrimSpace(part); trimmed != "" {
				out = append(out, trimmed)
			}
		}
	}
	if len(out) == 0 {
		return nil
	}
	return out
}

// HTTPStatus maps store/service errors to HTTP status codes.
func HTTPStatus(err error) int {
	switch {
	case errors.Is(err, api.ErrUnauthorized):
		return 401
	case errors.Is(err, agent.ErrUnauthorized):
		return 401
	case errors.Is(err, api.ErrForbidden):
		return 403
	case errors.Is(err, api.ErrNotFound):
		return 404
	case errors.Is(err, api.ErrConflict):
		return 409
	case errors.Is(err, api.ErrBadRequest):
		return 400
	case errors.Is(err, taskboard.ErrForbidden):
		return 403
	case errors.Is(err, taskboard.ErrNotFound):
		return 404
	case errors.Is(err, taskboard.ErrConflict):
		return 409
	case errors.Is(err, taskboard.ErrBadRequest):
		return 400
	case errors.Is(err, taskboard.ErrInvalidChannelTarget):
		return 400
	case errors.Is(err, message.ErrForbidden):
		return 403
	case errors.Is(err, message.ErrNotFound):
		return 404
	case errors.Is(err, message.ErrConflict):
		return 409
	case errors.Is(err, storeerr.ErrForbidden):
		return 403
	case errors.Is(err, storeerr.ErrNotFound):
		return 404
	case errors.Is(err, storeerr.ErrConflict):
		return 409
	case errors.Is(err, domain.ErrInvalidArgument):
		return 400
	case errors.Is(err, message.ErrMessageSearchUnavailable):
		return 501
	case errors.Is(err, owner.ErrOwnerMismatch):
		return http.StatusMisdirectedRequest
	default:
		return 500
	}
}
