package service

import (
	"cmp"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

// ==================== 常量定义 ====================

// AppVersion 应用版本号（发布时直接修改此处）
const AppVersion = "0.4.0"

// 版本号缓存
var (
	cachedVersion string
	versionOnce   sync.Once
)

// ==================== 类型定义 ====================

// Version 版本号结构
type Version struct {
	Major int
	Minor int
	Patch int
}

// WailsConfig Wails 配置文件结构
type WailsConfig struct {
	Version string `json:"version"`
}

// ==================== 版本号解析和比较 ====================

// ParseVersion 解析版本号字符串（支持 v1.0.0 或 1.0.0 格式）
func ParseVersion(versionStr string) (*Version, error) {
	versionStr = strings.TrimPrefix(versionStr, "v")
	parts := strings.Split(versionStr, ".")
	if len(parts) != 3 {
		return nil, fmt.Errorf("版本号格式错误，应为 x.y.z 格式")
	}

	major, err := strconv.Atoi(parts[0])
	if err != nil {
		return nil, fmt.Errorf("主版本号解析失败: %v", err)
	}

	minor, err := strconv.Atoi(parts[1])
	if err != nil {
		return nil, fmt.Errorf("次版本号解析失败: %v", err)
	}

	patch, err := strconv.Atoi(parts[2])
	if err != nil {
		return nil, fmt.Errorf("修订号解析失败: %v", err)
	}

	return &Version{Major: major, Minor: minor, Patch: patch}, nil
}

// Compare 比较版本号
// 返回值：-1 表示当前版本小于目标版本，0 表示相等，1 表示大于
func (v *Version) Compare(other *Version) int {
	switch {
	case v.Major != other.Major:
		return cmp.Compare(v.Major, other.Major)
	case v.Minor != other.Minor:
		return cmp.Compare(v.Minor, other.Minor)
	case v.Patch != other.Patch:
		return cmp.Compare(v.Patch, other.Patch)
	default:
		return 0
	}
}

// IsNewerThan 判断是否比目标版本新
func (v *Version) IsNewerThan(other *Version) bool {
	return v.Compare(other) > 0
}

// ==================== 版本号获取 ====================

// GetCurrentVersion 获取当前版本号（带缓存）
// 优先级：硬编码版本号 > wails.json（开发模式）> 默认值
func GetCurrentVersion() string {
	versionOnce.Do(func() {
		if AppVersion != "" {
			cachedVersion = AppVersion
			return
		}

		version := getVersionFromWailsJSON()
		if version != "" {
			cachedVersion = version
			return
		}

		cachedVersion = "0.0.1"
	})

	return cachedVersion
}

// ==================== 配置文件读取 ====================

// getVersionFromWailsJSON 从 wails.json 读取版本号（仅开发模式使用）
func getVersionFromWailsJSON() string {
	wd, err := os.Getwd()
	if err != nil {
		return ""
	}

	// 尝试当前目录
	if version := readVersionFromFile(filepath.Join(wd, "wails.json")); version != "" {
		return version
	}

	// 尝试父目录
	if version := readVersionFromFile(filepath.Join(filepath.Dir(wd), "wails.json")); version != "" {
		return version
	}

	return ""
}

// readVersionFromFile 从指定文件读取版本号
func readVersionFromFile(filePath string) string {
	data, err := os.ReadFile(filePath)
	if err != nil {
		log.Printf("[版本] 读取文件失败: %s, 错误: %v", filePath, err)
		return ""
	}

	var config WailsConfig
	if err := json.Unmarshal(data, &config); err != nil {
		log.Printf("[版本] 解析 JSON 失败: %s, 错误: %v", filePath, err)
		return ""
	}

	if config.Version != "" {
		log.Printf("[版本] 从文件读取版本号: %s -> %s", filePath, config.Version)
	}
	return config.Version
}
