package common

import (
	"errors"

	"github.com/gitlink-org/gitlink-cli/internal/client"
	clierrors "github.com/gitlink-org/gitlink-cli/internal/errors"
	"github.com/gitlink-org/gitlink-cli/internal/output"
)

// TryPrintError 尝试把 error 转换为 envelope 格式并输出到 stdout。
// 返回 true 表示已识别并处理；false 表示该 error 类型不被识别，应由调用方走原有路径。
//
// 设计意图：让 shortcut 的错误处理路径与 api 命令对齐，
// 使 `--format json` 输出可被 jq 解析的标准 envelope：
//
//	{"ok":false, "error":{"code":N, "message":"...", "suggestion":"..."}}
//
// 支持的 error 类型：
//   - *client.APIError  : HTTP 错误（404/403/401 等），code = HTTP 状态码
//   - *clierrors.CLIError : 业务级错误（输入/认证/网络等），code 由 kind 映射
//
// 注：放在 common 包（而非 output 包）以避免与 client 包形成导入循环。
func TryPrintError(err error, format string) bool {
	if err == nil {
		return false
	}

	var apiErr *client.APIError
	if errors.As(err, &apiErr) {
		env := output.ErrorEnvelope(apiErr.Code, apiErr.Message, apiErr.Suggestion)
		_ = output.Print(env, format)
		return true
	}

	var cliErr *clierrors.CLIError
	if errors.As(err, &cliErr) {
		env := output.ErrorEnvelope(kindToCode(cliErr.Kind), cliErr.Message, cliErr.Suggestion)
		_ = output.Print(env, format)
		return true
	}

	return false
}

// kindToCode 把 CLIError.Kind 映射到近似的 HTTP 状态码，用于 envelope.error.code 字段
func kindToCode(kind clierrors.ErrorKind) int {
	switch kind {
	case clierrors.KindAuth:
		return 401
	case clierrors.KindInput:
		return 400
	case clierrors.KindNotFound:
		return 404
	case clierrors.KindForbidden:
		return 403
	case clierrors.KindNetwork:
		return 503
	case clierrors.KindServer:
		return 500
	case clierrors.KindConfig:
		return 500
	case clierrors.KindGit:
		return 500
	default:
		return 500
	}
}
