package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"path/filepath"

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


const client_id string = "9305aeb8-5ecb-4e7a-b28f-c33aefcfbd8d"

// App struct
type App struct {
	Ctx   context.Context
	PrismLauncher Prism
	Java JavaManager
	Instance InstanceManager
	Modpacks ModpackManager
	Auth authenticationResp
}


// NewApp creates a new App application struct
func NewApp() *App {
	a := &App{}
	a.Java = JavaManager{app: a}
	a.Instance = InstanceManager{app: a}
	a.Modpacks = ModpackManager{app: a}
	return a
}

// 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
}

// Greet returns a greeting for the given name


func (a *App) CheckPrerequisites() {
	a.Status("Querrying Existing Instances")
	a.Instance.SearchInstances()
	a.Status("Pulling Modpacks")
	a.Modpacks.QuerryModpacks()
	a.Status("Logging in with Microsoft")
	dir, _ := os.UserConfigDir()	
	authenticated := false
	if _, err := os.Stat(filepath.Join(dir, "FCLauncher", "authentication.json")); err == nil {		
		f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "authentication.json"), os.O_RDONLY, 0755)
		defer f.Close()
		data, _ := io.ReadAll(f)
		json.Unmarshal(data, &a.Auth)
		a.Auth, err = TokenRefresh(*a, a.Auth)
		if err == nil {
			authenticated = true
		}
	}
	if !authenticated {
		var err error
		a.Auth, err = AuthCode(*a)
		if err != nil {
			fmt.Printf("Authentication Error: %s\n", err)
			return
		}
	}
	os.MkdirAll(filepath.Join(dir, "FCLauncher"), 0755)
	f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "authentication.json"), os.O_CREATE|os.O_RDWR, 0755)
	defer f.Close()
	data, _ := json.Marshal(a.Auth)
	f.Write(data)
}

func (App) GetVersions() ([]string, error) {
	manifest, err := GetVersionManifest()
	if err != nil {
		fmt.Printf("Manifest Error: %s\n", err)
		return []string{}, err
	}
	versions := []string{}
	for _, version := range manifest.Versions {
		versions = append(versions, version.Id)
	}
	return versions, nil

}

func (a *App) Status(status string) {
	fmt.Printf("LOG: %s\n", status)
	runtime.EventsEmit(a.Ctx, "status", status)
}
