package main

import (
	"log"
	"os/user"
	"slices"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"

	_ "embed"
)

type ActionConfig struct {
	username string
	password string
	hostname string
	port     int
}

const (
	appName string = "Systemec RaspScreen"
)

//go:embed icon.ico
var iconData []byte
var (
	windowSize  fyne.Size = fyne.NewSize(750, 700) // Default Window size
	buttonSize  fyne.Size = fyne.NewSize(200, 50)  // Default button size
	dButtonSize fyne.Size = fyne.NewSize(150, 50)  // Button size for upload & reload
	entrySize   fyne.Size = fyne.NewSize(200, 40)
)

func main() {
	iconResource := fyne.NewStaticResource("./src/icon.ico", iconData)
	//iconResource, _ := fyne.LoadResourceFromURLString("https://www.systemec.nl/favicon.ico")
	//iconResource, _ := fyne.LoadResourceFromPath("./icon.ico")

	app := app.NewWithID("nl.systemec.raspscreen")
	app.Settings().SetTheme(theme.DefaultTheme())
	app.SetIcon(iconResource)

	w := app.NewWindow(appName)
	w.Resize(windowSize)
	w.SetIcon(iconResource)

	uCtx, err := user.Current()
	if err != nil {
		log.Fatal("Unable to determine user")
	}
	username := uCtx.Username

	cfg, ok := readConfig()
	if !ok {
		dialog.ShowInformation("Failed to initialize", "Failed to read or unmarshal the raspis.yaml", w)
	}

	raspiNames := getRaspiNames(cfg, username)

	// Define variables and print them out for debug
	// Presentation = 1
	// Video = 2
	var targetMode int = 0
	var raspiTarget string = ""
	var localUploadPath string

	// Predefine the containers in total
	var modeBtnRow *fyne.Container
	var fileSelectRow *fyne.Container
	var tgrtSelectionRow *fyne.Container
	var footerRow *fyne.Container

	// Predefine the buttons for future reference
	var uploadBtn *widget.Button
	var reloadBtn *widget.Button
	var fSelecBtn *widget.Button

	// Predefine some of the labels
	var pathLabel *widget.Label

	log.Println("Current mode:", targetMode)
	if raspiTarget == "" {
		log.Println("Current target: None")
	} else {
		log.Println("Current target:", raspiTarget)
	}

	// Call the draw functions -> ./src/draw.go
	footerRow, uploadBtn, reloadBtn = drawFooter(app, &raspiTarget, &localUploadPath, &targetMode, cfg)
	fileSelectRow, fSelecBtn, pathLabel = drawFileSelection(&localUploadPath, &targetMode, fSelecBtn, w)
	modeBtnRow = drawModeRow(&localUploadPath, &targetMode, fSelecBtn, pathLabel)
	tgrtSelectionRow = drawTargetSection(raspiNames, &raspiTarget, uploadBtn, reloadBtn, cfg)

	center := container.NewVBox(
		modeBtnRow,
		widget.NewLabel(""),
		fileSelectRow,
		drawSeparator(true, true),
		tgrtSelectionRow,
	)

	content := container.NewBorder(
		nil,
		footerRow, // bottom
		nil,
		nil,    // left, right
		center, //center
	)

	w.SetContent(content)
	w.ShowAndRun()
}

func refreshButtons(givenButtons ...*widget.Button) {
	for _, b := range givenButtons {
		btn := b
		fyne.CurrentApp().Driver().DoFromGoroutine(func() {
			btn.Refresh()
		}, false)
	}
}

// The raspiList is defined in the other go file, must me maintained separately
func getRaspiNames(cfg RaspiConfig, username string) []string {
	raspiNames := make([]string, 0, len(cfg.Raspis))

	var superAdminPresent bool
	if len(cfg.SuperAdmin) == 0 {
		superAdminPresent = false
	} else {
		superAdminPresent = true
	}
	log.Printf("Adding super_admin to the authorized_users at runtime: %s", cfg.SuperAdmin)
	// Append the name of the pi to the list we need for the radio button
	// i is the index field correlated to the name as per defined in rpi-list.go
	for _, indPi := range cfg.Raspis {
		if superAdminPresent {
			indPi.AuthorizedUsers = append(indPi.AuthorizedUsers, cfg.SuperAdmin) // Append the superadmin to the authorized users
		}

		if allowedUser(indPi.AuthorizedUsers, username) {
			raspiNames = append(raspiNames, indPi.Name) // append only the first element
		}
	}

	return raspiNames
}

func allowedUser(authorized_users []string, username string) bool {
	if len(authorized_users) == 0 {
		return false
	}

	if slices.Contains(authorized_users, username) {
		log.Printf("Found a match for the user %s", username)
		return true
	} else {
		return false
	}
}
