package main

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	goruntime "runtime"

	wr "github.com/wailsapp/wails/v2/pkg/runtime"
)

// App 经 Wails 的 TS/Go 强绑定暴露给前端，承载只有桌面端能做的原生能力：
// 文件读写、系统"另存为"框、用系统默认应用打开、原生通知。
type App struct {
	ctx context.Context
}

func NewApp() *App { return &App{} }

// startup 在 Wails 启动时注入运行时 ctx。
func (a *App) startup(ctx context.Context) { a.ctx = ctx }

// Ping 供前端探活 Go 桥是否就绪。
func (a *App) Ping() string { return "sundynix-desktop ok" }

// ReadLocalFile 读取本地文件内容（本地文件系统 I/O）。
func (a *App) ReadLocalFile(path string) (string, error) {
	b, err := os.ReadFile(path)
	if err != nil {
		return "", err
	}
	return string(b), nil
}

// SaveReportAs 弹原生"另存为"对话框，把 url 指向的报告（.docx）下载到用户选定路径。
// 返回保存路径；用户取消则返回空串。
func (a *App) SaveReportAs(url, filename string) (string, error) {
	if filename == "" {
		filename = "report.docx"
	}
	path, err := wr.SaveFileDialog(a.ctx, wr.SaveDialogOptions{
		Title:           "保存报告",
		DefaultFilename: filename,
		Filters:         []wr.FileFilter{{DisplayName: "Word 文档 (*.docx)", Pattern: "*.docx"}},
	})
	if err != nil || path == "" {
		return "", err
	}
	if err := download(url, path); err != nil {
		return "", err
	}
	return path, nil
}

// OpenReport 把报告下载到临时目录，并用系统默认应用（Word/Pages/WPS）打开。
func (a *App) OpenReport(url, filename string) error {
	if filename == "" {
		filename = "report.docx"
	}
	dst := filepath.Join(os.TempDir(), "sundynix-open-"+filename)
	if err := download(url, dst); err != nil {
		return err
	}
	return openInSystem(dst)
}

// Notify 弹一条系统通知（best-effort：macOS 用 osascript，其它平台暂静默）。
func (a *App) Notify(title, body string) {
	if goruntime.GOOS == "darwin" {
		script := fmt.Sprintf("display notification %q with title %q", body, title)
		_ = exec.Command("osascript", "-e", script).Start()
	}
}

func download(url, dst string) error {
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode >= 400 {
		return fmt.Errorf("下载失败 HTTP %d", resp.StatusCode)
	}
	f, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = io.Copy(f, resp.Body)
	return err
}

func openInSystem(path string) error {
	switch goruntime.GOOS {
	case "darwin":
		return exec.Command("open", path).Start()
	case "windows":
		return exec.Command("rundll32", "url.dll,FileProtocolHandler", path).Start()
	default:
		return exec.Command("xdg-open", path).Start()
	}
}
