package main

import (
	"embed"
	"fmt"
	"log"
	"log/slog"
	"net/http"
	"net/url"

	"git.codemonkeysoftware.net/b/peachy-go"
	"git.codemonkeysoftware.net/b/peachy-go/desktop/routes"
	"github.com/wailsapp/wails/v3/pkg/application"
)

//go:embed all:static
var assets embed.FS

const ListenPort = "9245"
const WindowNameMain = "mainwindow"

var globalDB peachy.DB

func closeDB() {
	globalDB.Close()
}

// SetURl is a workaround for WebviewWindow.SetURL not adding the base URL
// to relative URLs.
// TODO Report this or something.
func SetURL(win application.Window, path string) application.Window {
	slog.Info("setting URL the hard way")
	u, _ := url.JoinPath("http://wails.localhost:"+ListenPort+"/", path)
	return win.SetURL(u)
}

func setDB(db peachy.DB) error {
	slog.Info("opened DB, setting URL")
	globalDB = db
	SetURL(application.Get().GetWindowByName(WindowNameMain), "/site")
	return nil
}

func createDB(filename string) error {
	db, err := peachy.Create(filename)
	if err != nil {
		return fmt.Errorf("Failed to create database: %w", err)
	}
	return setDB(db)
}

func openDB(filename string) error {
	db, err := peachy.Open(filename)
	if err != nil {
		return fmt.Errorf("Failed to open database: %w", err)
	}
	return setDB(db)
}

func showError(err error) {
	if err != nil {
		application.ErrorDialog().SetMessage(err.Error()).Show()
	}
}

func dbFileFilter() []application.FileFilter {
	return []application.FileFilter{
		{DisplayName: "Peachy database", Pattern: "*.pit"},
		{DisplayName: "All Files", Pattern: "*.*"},
	}
}

func main() {
	r := routes.NewChiRouter(ListenPort, &globalDB)

	app := application.New(application.Options{
		Name:        "Peachy",
		Description: "A desktop CMS for static sites",
		Assets: application.AssetOptions{
			Handler: application.AssetFileServerFS(assets),
			Middleware: func(next http.Handler) http.Handler {
				r.NotFound(next.ServeHTTP)
				return r
			},
		},
		Mac: application.MacOptions{
			ApplicationShouldTerminateAfterLastWindowClosed: true,
		},
	})
	app.OnShutdown(func() {
		closeDB()
	})

	app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
		Name:  WindowNameMain,
		Title: "Your Project",
		Mac: application.MacWindow{
			Backdrop: application.MacBackdropTranslucent,
		},
		URL:      "/",  // URL to load when the window is created
		Width:    1080, // Width of the window
		Height:   720,  // Height of the window
		Centered: false,
	})

	menu := app.NewMenu()
	fileMenu := menu.AddSubmenu("File")
	fileMenu.AddRole(application.NewFile)
	fileMenu.AddRole(application.Open)
	fileMenu.Append(application.NewFileMenu().GetSubmenu())
	menu.FindByRole(application.NewFile).OnClick(func(ctx *application.Context) {
		d := application.SaveFileDialog()
		d.SetOptions(&application.SaveFileDialogOptions{
			Filters:             dbFileFilter(),
			AllowOtherFileTypes: true,
			Title:               "Create new database",
		})
		path, _ := d.PromptForSingleSelection()
		if path != "" {
			showError(createDB(path))
		}
	})
	menu.FindByRole(application.Open).OnClick(func(ctx *application.Context) {
		d := application.OpenFileDialog()
		d.SetOptions(&application.OpenFileDialogOptions{
			Filters:        dbFileFilter(),
			CanChooseFiles: true,
		})
		path, _ := d.PromptForSingleSelection()
		if path != "" {
			showError(openDB(path))
		}
	})
	app.SetMenu(menu)

	err := app.Run()

	if err != nil {
		log.Fatal(err)
	}
}
