package sftp

import (
	"errors"
	"fmt"
	"strings"
)

// ConnectionError SFTP 连接错误（区分阶段）
type ConnectionError struct {
	Op  string // dial / handshake / auth / sftp_init
	Err error
}

func (e *ConnectionError) Error() string {
	return fmt.Sprintf("SFTP 连接失败 [%s]: %v", e.Op, e.Err)
}

func (e *ConnectionError) Unwrap() error { return e.Err }

// ToUserMessage 将底层错误转换为用户友好的中文错误（返回 error 类型）
func ToUserMessage(err error) error {
	if err == nil {
		return nil
	}

	var connErr *ConnectionError
	if errors.As(err, &connErr) {
		switch connErr.Op {
		case "dial":
			return fmt.Errorf("无法连接到服务器 (%v)。请检查地址和端口是否正确", connErr.Err)
		case "handshake":
			return fmt.Errorf("SSH 握手失败，请检查服务是否正常运行")
		case "auth":
			return fmt.Errorf("认证失败，请检查用户名和密码/密钥是否正确")
		case "sftp_init":
			return fmt.Errorf("SFTP 子系统初始化失败，请确认远程服务器支持 SFTP")
		}
	}

	msg := err.Error()
	switch {
	case strings.Contains(msg, "unable authenticate"), strings.Contains(msg, "no auth method"):
		return fmt.Errorf("认证失败：用户名或密码/密钥不正确")
	case strings.Contains(msg, "connection refused"):
		return fmt.Errorf("连接被拒绝：目标机器可能未开启 SSH 服务")
	case strings.Contains(msg, "timeout"), strings.Contains(msg, "i/o timeout"):
		return fmt.Errorf("连接超时：请检查网络连通性或防火墙设置")
	case strings.Contains(msg, "host key mismatch"):
		return fmt.Errorf("主机密钥不匹配：可能存在中间人攻击风险")
	case strings.Contains(msg, "permission denied"):
		return fmt.Errorf("权限不足：当前用户无权访问该资源")
	case strings.Contains(msg, "no such file"), strings.Contains(msg, "not found"):
		return fmt.Errorf("文件或目录不存在")
	default:
		return err
	}
}

// isNetworkError 判断是否为网络层错误（需要重连）
func isNetworkError(err error) bool {
	if err == nil {
		return false
	}
	msg := strings.ToLower(err.Error())
	return strings.Contains(msg, "broken pipe") ||
		strings.Contains(msg, "connection reset") ||
		strings.Contains(msg, "timeout")
}
