package handler

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

// UpdateHandler 系统更新处理器
type UpdateHandler struct {
	httpClient     *http.Client
	currentVersion string
}

// NewUpdateHandler 创建系统更新处理器
func NewUpdateHandler(currentVersion string) *UpdateHandler {
	return &UpdateHandler{
		httpClient: &http.Client{
			Timeout: 10 * time.Second,
		},
		currentVersion: currentVersion,
	}
}

// GitHubRelease GitHub 发布响应结构
type GitHubRelease struct {
	TagName     string `json:"tag_name"`
	Name        string `json:"name"`
	Body        string `json:"body"`
	PublishedAt string `json:"published_at"`
	HtmlURL     string `json:"html_url"`
	Assets      []struct {
		Name        string `json:"name"`
		DownloadURL string `json:"browser_download_url"`
		Size        int64  `json:"size"`
	} `json:"assets"`
}

// CheckUpdateResponse 检查更新响应
type CheckUpdateResponse struct {
	HasUpdate      bool   `json:"has_update"`
	LatestVersion  string `json:"latest_version"`
	CurrentVersion string `json:"current_version"`
	ReleaseNotes   string `json:"release_notes"`
	DownloadURL    string `json:"download_url"`
	PublishedAt    string `json:"published_at"`
	Error          string `json:"error,omitempty"`
}

// CheckUpdate 检查更新
// @Summary 检查系统更新
// @Tags System
// @Accept json
// @Produce json
// @Success 200 {object} CheckUpdateResponse
// @Router /api/v1/system/update/check [get]
func (h *UpdateHandler) CheckUpdate() (*CheckUpdateResponse, error) {
	// Gitea Releases API
	repo := "zkcoi/meshray"
	url := fmt.Sprintf("https://git.zkcoi.com/api/v1/repos/%s/releases/latest", repo)

	resp, err := h.httpClient.Get(url)
	if err != nil {
		return &CheckUpdateResponse{
			HasUpdate:      false,
			CurrentVersion: h.currentVersion,
			Error:          "检查更新失败：" + err.Error(),
		}, nil
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return &CheckUpdateResponse{
			HasUpdate:      false,
			CurrentVersion: h.currentVersion,
			Error:          "读取响应失败：" + err.Error(),
		}, nil
	}

	var release GitHubRelease
	if err := json.Unmarshal(body, &release); err != nil {
		return &CheckUpdateResponse{
			HasUpdate:      false,
			CurrentVersion: h.currentVersion,
			Error:          "解析响应失败：" + err.Error(),
		}, nil
	}

	// 移除版本号前缀的 'v'
	latestVersion := release.TagName
	if len(latestVersion) > 0 && latestVersion[0] == 'v' {
		latestVersion = latestVersion[1:]
	}

	currentVersion := h.currentVersion
	if len(currentVersion) > 0 && currentVersion[0] == 'v' {
		currentVersion = currentVersion[1:]
	}

	// 比较版本号
	hasUpdate := compareVersions(latestVersion, currentVersion) > 0

	downloadURL := release.HtmlURL
	if len(release.Assets) > 0 {
		// 优先选择 Windows 可执行文件
		for _, asset := range release.Assets {
			if asset.Name == "meshray.exe" {
				downloadURL = asset.DownloadURL
				break
			}
		}
	}

	return &CheckUpdateResponse{
		HasUpdate:      hasUpdate,
		LatestVersion:  release.TagName,
		CurrentVersion: h.currentVersion,
		ReleaseNotes:   release.Body,
		DownloadURL:    downloadURL,
		PublishedAt:    release.PublishedAt,
	}, nil
}

// compareVersions 比较版本号
// 返回：1 (v1 > v2), 0 (v1 == v2), -1 (v1 < v2)
func compareVersions(v1, v2 string) int {
	if v1 == v2 {
		return 0
	}

	// 简单版本号比较（格式：major.minor.patch）
	parts1 := parseVersion(v1)
	parts2 := parseVersion(v2)

	for i := 0; i < len(parts1) && i < len(parts2); i++ {
		if parts1[i] > parts2[i] {
			return 1
		} else if parts1[i] < parts2[i] {
			return -1
		}
	}

	// 如果前面都相同，比较长度
	if len(parts1) > len(parts2) {
		return 1
	}
	return -1
}

// parseVersion 解析版本号字符串为整数数组
func parseVersion(version string) []int {
	var parts []int
	current := 0

	for i, ch := range version {
		if ch == '.' {
			parts = append(parts, current)
			current = 0
		} else if ch >= '0' && ch <= '9' {
			current = current*10 + int(ch-'0')
		}

		// 处理最后一个字符
		if i == len(version)-1 {
			parts = append(parts, current)
		}
	}

	return parts
}
