package internal

import (
	"firefly-launcher/pkg/sevenzip"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"github.com/wailsapp/wails/v3/pkg/application"
	"golang.org/x/sys/windows"
)

type FSService struct{}

func (f *FSService) PickFolder() (string, error) {
	dialog := application.OpenFileDialog().
		CanChooseDirectories(true).
		CanCreateDirectories(true).
		ResolvesAliases(true)
	if runtime.GOOS == "darwin" {
		dialog.SetMessage("Select a file/directory")
	} else {
		dialog.SetTitle("Select a file/directory")
	}
	if path, err := dialog.PromptForSingleSelection(); err == nil {
		return path, nil
	}
	return "", nil
}

func (f *FSService) PickFile() (string, error) {
	dialog := application.OpenFileDialog().
		CanChooseFiles(true).
		ResolvesAliases(true)
	if runtime.GOOS == "darwin" {
		dialog.SetMessage("Select a file/directory")
	} else {
		dialog.SetTitle("Select a file/directory")
	}
	if path, err := dialog.PromptForSingleSelection(); err == nil {
		return path, nil
	}
	return "", nil
}

func (f *FSService) DirExists(path string) bool {
	info, err := os.Stat(path)
	if err != nil {
		return false
	}
	return info.IsDir()
}

func (f *FSService) FileExists(path string) bool {
	if info, err := os.Stat(path); err == nil {
		return info.Mode().IsRegular()
	}
	return false
}

func (f *FSService) StartApp(path string) (bool, error) {
	cmd := exec.Command(path)
	err := cmd.Start()
	if err != nil {
		return false, err
	}
	if strings.HasSuffix(path, "StarRail.exe") {
		go func() {
			_ = cmd.Wait()
			application.Get().EmitEvent("game:exit")
		}()
	}

	return true, nil
}

func (f *FSService) StartWithConsole(path string) (bool, error) {
	absPath, err := filepath.Abs(path)
	if err != nil {
		return false, err
	}

	if _, err := os.Stat(absPath); os.IsNotExist(err) {
		return false, fmt.Errorf("file not found: %s", absPath)
	}
	cmd := exec.Command(absPath)
	cmd.Dir = filepath.Dir(absPath)
	cmd.Stdin = nil
	cmd.Stdout = nil
	cmd.Stderr = nil

	cmd.SysProcAttr = &windows.SysProcAttr{
		CreationFlags: windows.CREATE_NEW_CONSOLE |
			windows.CREATE_BREAKAWAY_FROM_JOB,
		NoInheritHandles: true,
	}

	err = cmd.Start()

	if err != nil {
		return false, err
	}

	go func() {
		_ = cmd.Wait()
		if strings.HasSuffix(path, "launcher.exe") {
			application.Get().EmitEvent("game:exit")
		} else if strings.HasSuffix(path, "firefly-go_win.exe") {
			application.Get().EmitEvent("server:exit")
		} else if strings.HasSuffix(path, "FireflyProxy.exe") {
			application.Get().EmitEvent("proxy:exit")
		}
	}()
	return true, nil
}

func (f *FSService) OpenFolder(path string) (bool, string) {
	absPath, err := filepath.Abs(path)
	if err != nil {
		return false, "failed to resolve absolute path: " + err.Error()
	}

	if !f.DirExists(absPath) {
		return false, "directory not found: " + absPath
	}

	url := "file:///" + filepath.ToSlash(absPath)
	application.Get().BrowserOpenURL(url)

	return true, ""
}

func (f *FSService) FileExistsInZip(archivePath, fileInside string) (bool, string) {
	exists, err := sevenzip.IsFileIn7z(archivePath, fileInside)
	if err != nil {
		return false, err.Error()
	}
	return exists, ""
}

