package main

import (
	"embed"
	"os"
	"runtime"

	"github.com/wailsapp/wails/v2"
	"github.com/wailsapp/wails/v2/pkg/options"
	"github.com/wailsapp/wails/v2/pkg/options/assetserver"

	"cdrop-desktop/platform"
)

//go:embed all:frontend/dist
var assets embed.FS

func main() {
	// Create an instance of the app structure
	app := NewApp()

	// Reverse-proxy /api/* to the backend so the embedded web UI can keep its
	// same-origin relative URLs (see platform.NewAPIProxy). SSE streams through.
	apiProxy, err := platform.NewAPIProxy(app.apiBase)
	if err != nil {
		println("Error:", err.Error())
		return
	}

	// Windows: Wails' custom-scheme AssetServer buffers a handler's response until
	// it returns, so the long-lived SSE never reaches the WebView (device list
	// never loads, status stuck on "connecting"). Serve /api from a loopback HTTP
	// origin instead — WebView2's normal network stack streams it — and point the
	// page there via the injected api_base. macOS streams the custom scheme fine,
	// so it keeps api_base="" (same-origin relative /api through apiProxy).
	webAPIBase := ""
	if runtime.GOOS == "windows" {
		if base, lerr := platform.StartLocalAPIServer(app.apiBase); lerr == nil {
			webAPIBase = base
		} else {
			println("local api server:", lerr.Error())
		}
	}

	// Tell the backend this is a native desktop client, not a browser, so the
	// device list shows the right kind. The page forwards it as X-Device-Type.
	deviceType := platform.DeviceType()

	// Restore the persisted login + device name by injecting them into index.html
	// at load — the wails:// scheme has no persistent WebView storage (see
	// session.go).
	session, _ := platform.LoadSession()
	// Heal a stale display identity (older builds baked the subject UUID and no avatar into
	// the on-disk session) from the authoritative /api/me, and re-persist, BEFORE injecting it
	// — so the name + picture are correct on every launch instead of depending on a fragile
	// per-launch WebView /api/me (the source of the intermittent UUID regression). Bounded +
	// best-effort: offline keeps the persisted identity.
	session = platform.HealIdentity(session, app.apiBase)

	// When the OS starts us at login, the autostart entry appends a --hidden flag
	// (see SetLaunchAtLogin). Come up straight to the menu bar / tray with no
	// window — the user didn't open the app, so don't steal focus. The frontend
	// still loads, so clipboard sync runs in the background. A manual launch has
	// no flag and shows the window as usual.
	hidden := launchedHidden()
	app.startHidden = hidden

	// Create application with options
	err = wails.Run(&options.App{
		Title:       "cdrop",
		Width:       1024,
		Height:      768,
		StartHidden: hidden,
		AssetServer: &assetserver.Options{
			Assets:     assets,
			Handler:    apiProxy,
			Middleware: platform.SessionInjectMiddleware(session, platform.ResolveDeviceName(), webAPIBase, deviceType),
		},
		BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
		Menu:             app.buildMenu(),
		OnStartup:        app.startup,
		OnBeforeClose:    app.beforeClose,
		Bind: []interface{}{
			app,
		},
	})

	if err != nil {
		println("Error:", err.Error())
	}
}

// launchedHidden reports whether this process was started by the login autostart
// entry, which appends a --hidden flag to the launch command (see
// SetLaunchAtLogin on each platform). Manual launches never carry it.
func launchedHidden() bool {
	for _, arg := range os.Args[1:] {
		if arg == "--hidden" {
			return true
		}
	}
	return false
}
