package config

import (
	"fmt"
	"net/url"
	"regexp"
	"strconv"
	"strings"
)

// ValidationResult 验证结果
type ValidationResult struct {
	Valid    bool
	Errors   []string
	Warnings []string
}

// ValidateConfigAdvanced 高级配置验证
func ValidateConfigAdvanced(config *Config) *ValidationResult {
	result := &ValidationResult{
		Valid:    true,
		Errors:   []string{},
		Warnings: []string{},
	}

	// 基础验证
	if err := ValidateConfig(config); err != nil {
		result.Valid = false
		result.Errors = append(result.Errors, err.Error())
	}

	// 高级验证
	validateSecretKeys(config, result)
	validateBucketNaming(config, result)
	validateRegionConfig(config, result)
	validateCustomDomain(config, result)
	validateWebServerConfig(config, result)
	validateSecuritySettings(config, result)

	return result
}

// validateSecretKeys 验证密钥格式和安全性
func validateSecretKeys(config *Config, result *ValidationResult) {
	// SecretId 格式验证
	if !isValidSecretId(config.SecretId) {
		result.Valid = false
		result.Errors = append(result.Errors, "SecretId 格式无效，应为腾讯云SecretId格式")
	}

	// SecretKey 格式验证
	if !isValidSecretKey(config.SecretKey) {
		result.Valid = false
		result.Errors = append(result.Errors, "SecretKey 格式无效，应为腾讯云SecretKey格式")
	}

	// 安全性警告
	if strings.Contains(config.SecretId, "test") || strings.Contains(config.SecretKey, "test") {
		result.Warnings = append(result.Warnings, "检测到测试密钥，生产环境请使用正式密钥")
	}
}

// validateBucketNaming 验证存储桶命名规范
func validateBucketNaming(config *Config, result *ValidationResult) {
	bucket := config.Bucket

	// 命名规范检查
	if !isValidBucketName(bucket) {
		result.Valid = false
		result.Errors = append(result.Errors, "Bucket名称不符合腾讯云命名规范")
	}

	// 安全性建议
	if strings.Contains(bucket, "admin") || strings.Contains(bucket, "root") {
		result.Warnings = append(result.Warnings, "Bucket名称包含敏感词汇，建议使用更安全的名称")
	}

	// 长度建议
	if len(bucket) > 30 {
		result.Warnings = append(result.Warnings, "Bucket名称较长，建议使用较短名称以提高访问效率")
	}
}

// validateRegionConfig 验证区域配置
func validateRegionConfig(config *Config, result *ValidationResult) {
	region := config.Region

	// 检查区域是否受支持
	supportedRegions := getSupportedRegions()
	if !isSupportedRegion(region, supportedRegions) {
		result.Valid = false
		result.Errors = append(result.Errors, fmt.Sprintf("区域 %s 不受支持，支持的区域: %s", region, strings.Join(supportedRegions, ", ")))
	}

	// 性能建议
	if strings.HasPrefix(region, "ap-") {
		result.Warnings = append(result.Warnings, "亚太区域访问速度较快，适合国内用户")
	}
}

// validateCustomDomain 验证自定义域名配置
func validateCustomDomain(config *Config, result *ValidationResult) {
	domain := config.CustomDomain

	if domain == "" {
		result.Warnings = append(result.Warnings, "未配置自定义域名，将使用腾讯云默认域名")
		return
	}

	// URL格式验证
	if !strings.HasPrefix(domain, "http://") && !strings.HasPrefix(domain, "https://") {
		result.Warnings = append(result.Warnings, "建议域名包含协议前缀 (http:// 或 https://)")
	}

	// 解析URL
	parsedURL, err := url.Parse(domain)
	if err != nil {
		result.Valid = false
		result.Errors = append(result.Errors, "自定义域名格式无效")
		return
	}

	// SSL建议
	if parsedURL.Scheme == "http" {
		result.Warnings = append(result.Warnings, "建议使用 HTTPS 协议以提高安全性")
	}

	// 域名有效性检查
	if !IsValidDomain(parsedURL.Host) {
		result.Valid = false
		result.Errors = append(result.Errors, "自定义域名格式无效")
	}
}

// validateSecuritySettings 验证安全设置
func validateSecuritySettings(config *Config, result *ValidationResult) {
	// 检查密钥强度
	if len(config.SecretId) < 20 || len(config.SecretKey) < 30 {
		result.Warnings = append(result.Warnings, "建议使用更强度的密钥")
	}

	// 网络安全建议
	if config.CustomDomain != "" && strings.HasPrefix(config.CustomDomain, "http://") {
		result.Warnings = append(result.Warnings, "HTTP协议不安全，建议使用HTTPS")
	}
}

// validateWebServerConfig 验证 Web 服务配置
func validateWebServerConfig(config *Config, result *ValidationResult) {
	address := strings.TrimSpace(config.WebServer.Address)
	if address == "" {
		result.Valid = false
		result.Errors = append(result.Errors, "webserver.address 不能为空")
		return
	}

	host, port, ok := strings.Cut(address, ":")
	if !ok {
		result.Valid = false
		result.Errors = append(result.Errors, "webserver.address 格式无效，应为 host:port")
		return
	}

	if port == "" {
		result.Valid = false
		result.Errors = append(result.Errors, "webserver.address 必须包含端口")
	} else if _, err := strconv.Atoi(port); err != nil {
		result.Valid = false
		result.Errors = append(result.Errors, "webserver.address 端口必须为数字")
	}

	if host == "0.0.0.0" {
		result.Warnings = append(result.Warnings, "0.0.0.0 会暴露在所有网络接口上，请确认安全性")
	}
}

// 辅助函数

func isValidSecretId(secretId string) bool {
	// 腾讯云SecretId通常以AKID开头，长度在20-40字符之间
	if len(secretId) < 20 || len(secretId) > 40 {
		return false
	}

	// 检查是否包含非法字符
	matched, _ := regexp.MatchString(`^[a-zA-Z0-9-]+$`, secretId)
	return matched
}

func isValidSecretKey(secretKey string) bool {
	// 腾讯云SecretKey通常为32字符的字符串
	if len(secretKey) < 30 || len(secretKey) > 40 {
		return false
	}

	// 检查是否包含非法字符
	matched, _ := regexp.MatchString(`^[a-zA-Z0-9+/=]+$`, secretKey)
	return matched
}

func isValidBucketName(bucket string) bool {
	if len(bucket) < 3 || len(bucket) > 63 {
		return false
	}

	// 只能包含小写字母、数字和连字符
	matched, _ := regexp.MatchString(`^[a-z0-9-]+$`, bucket)
	if !matched {
		return false
	}

	// 不能以连字符开头或结尾
	if strings.HasPrefix(bucket, "-") || strings.HasSuffix(bucket, "-") {
		return false
	}

	// 不能包含连续的连字符
	if strings.Contains(bucket, "--") {
		return false
	}

	return true
}

func getSupportedRegions() []string {
	return []string{
		"ap-beijing", "ap-shanghai", "ap-guangzhou", "ap-chengdu", "ap-chongqing",
		"ap-singapore", "ap-hongkong", "ap-tokyo", "ap-seoul", "ap-mumbai",
		"na-toronto", "na-ashburn", "eu-frankfurt", "eu-london",
	}
}

func isSupportedRegion(region string, supportedRegions []string) bool {
	for _, supported := range supportedRegions {
		if region == supported {
			return true
		}
	}
	return false
}

// FormatValidationResult 格式化验证结果
func FormatValidationResult(result *ValidationResult) string {
	var builder strings.Builder

	if result.Valid {
		builder.WriteString("✅ 配置验证通过\n")
	} else {
		builder.WriteString("❌ 配置验证失败\n")
	}

	if len(result.Errors) > 0 {
		builder.WriteString("\n🚨 错误信息:\n")
		for i, err := range result.Errors {
			builder.WriteString(fmt.Sprintf("  %d. %s\n", i+1, err))
		}
	}

	if len(result.Warnings) > 0 {
		builder.WriteString("\n⚠️ 警告信息:\n")
		for i, warning := range result.Warnings {
			builder.WriteString(fmt.Sprintf("  %d. %s\n", i+1, warning))
		}
	}

	return builder.String()
}
