package main

import (
	"context"
	"errors"
	"fmt"
	"os"

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

// App struct
type App struct {
	ctx context.Context
	ssi *ESISSO
}

// NewApp creates a new App application struct
func NewApp() *App {
	return &App{}
}

// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
	a.ctx = ctx

	clientID := os.Getenv("EVE_SSO_CLIENT_ID")
	if clientID == "" {
		clientID = "5091f74037374697938384bdbac2698c"
	}
	redirectURI := os.Getenv("EVE_SSO_REDIRECT_URI")
	if redirectURI == "" {
		redirectURI = "http://localhost:8080/callback"
	}

	a.ssi = NewESISSO(clientID, redirectURI, []string{"esi-ui.write_waypoint.v1"})
}

// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
	return fmt.Sprintf("Hello %s, It's show time!", name)
}

// StartESILogin begins the PKCE SSO flow and opens a browser to the EVE login page
func (a *App) StartESILogin() (string, error) {
	if a.ssi == nil {
		return "", errors.New("ESI not initialised")
	}
	url, err := a.ssi.BuildAuthorizeURL()
	if err != nil {
		return "", err
	}
	if err := a.ssi.StartCallbackServerAsync(); err != nil {
		return "", err
	}
	runtime.BrowserOpenURL(a.ctx, url)
	return url, nil
}

// ESILoginStatus returns a short status string of the active token/character
func (a *App) ESILoginStatus() string {
	if a.ssi == nil {
		return "not initialised"
	}
	st := a.ssi.Status()
	if st.LoggedIn {
		return fmt.Sprintf("logged in as %s (%d)", st.CharacterName, st.CharacterID)
	}
	return "not logged in"
}

// ESILoggedIn returns true if a valid access token is present
func (a *App) ESILoggedIn() bool {
	if a.ssi == nil {
		return false
	}
	return a.ssi.Status().LoggedIn
}

// SetDestination posts a waypoint to ESI to set destination
func (a *App) SetDestination(destinationID int64, clearOthers bool, addToBeginning bool) error {
	if a.ssi == nil {
		return errors.New("ESI not initialised")
	}
	return a.ssi.PostWaypoint(destinationID, clearOthers, addToBeginning)
}

// SetDestinationByName resolves a solar system name to ID and sets destination
func (a *App) SetDestinationByName(systemName string, clearOthers bool, addToBeginning bool) error {
	if a.ssi == nil {
		return errors.New("ESI not initialised")
	}
	id, err := a.ssi.ResolveSystemIDByName(a.ctx, systemName)
	if err != nil {
		return err
	}
	return a.ssi.PostWaypoint(id, clearOthers, addToBeginning)
}
