package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"

	"github.com/fatih/color"
)

func clearScreen() {
	cmd := exec.Command("clear")
	out, err := cmd.CombinedOutput()
	if err != nil {
		searchRepo()
	}
	fmt.Print(string(out))
}
func input(s string) (string, error) {
	stdinBuf := bufio.NewReader(os.Stdin)

	fmt.Print(s)

	text, err := stdinBuf.ReadString('\n')
	if err != nil {
		panic(err)
	}
	return text[:len(text)-1], err
}

func searchRepo() {
	color.Set(color.FgHiCyan)
	print("\n| Search Repositories |\n")
	print("Enter a search term and copy the namespace to clipboard\n")
	print("Paste this later to the install menu.\n\n")
	print("Type: 'm' for main menu\n")
	print("Type: 'q' to quit the application\n\n")
	color.Unset()

	var programName, _ = input(">> ")

	trimInput := strings.TrimSpace(programName)

	if trimInput == "m" {
		return
	} else if trimInput == "q" {
		os.Exit(0)
	} else {
		cmd := exec.Command("flatpak", "search", trimInput)
		out, err := cmd.CombinedOutput()
		if err != nil {
			searchRepo()
		}
		color.Set(color.FgHiGreen)
		print("\n==============================================================\n")
		fmt.Print("Results for ", trimInput, ": \n\n", string(out), "\n")
		print("\n\n==============================================================\n")
		color.Unset()
		searchRepo()
	}
}

func installPak() {
	color.Set(color.FgHiCyan)
	print("\n| Install Menu |\n\n")
	print("To Use: Copy paste a flatpak namespace from search results\n\n")
	print("EXAMPLE: 'com.play0ad.zeroad' - installs the Game '0ad'\n\n")
	print("Type: 'm' for main menu\n")
	print("Type: 'q' to quit the application\n\n")
	print("NOTE: install can take several seconds and appear to hang. Please be patient...\n\n")
	color.Unset()
	var programName, _ = input(">> ")

	trimInput := strings.TrimSpace(programName)

	if trimInput == "m" {
		return

	} else if trimInput == "q" {
		os.Exit(0)

	} else {
		cmd := exec.Command("flatpak", "install", "-y", "flathub", trimInput)
		out, err := cmd.CombinedOutput()

		if err != nil {
			installPak()
		}
		color.Set(color.FgHiGreen)
		print("\n==========================================================================\n\n")
		fmt.Print(string(out), "\n")
		print("\n============================================================================\n\n")
		color.Unset()
		installPak()
	}
}

func listPak() {
	color.Set(color.FgHiGreen)
	print("\n| List of installed Flatpaks |\n")
	color.Unset()
	cmd := exec.Command("flatpak", "list")
	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatalf("cmd.Run() failed with %s\n", err)
	}

	color.Set(color.FgHiYellow)
	print("\n============================================================================\n\n")
	fmt.Print(string(out), "\n\n")
	print("\n============================================================================\n\n")
	color.Unset()
}

func removePak() {
	color.Set(color.FgHiCyan)
	print("\n| Remove Flatpaks |\n")
	color.Unset()
	listPak()
	color.Set(color.FgHiCyan)
	print("\n\nCopy and paste a namespace above and press enter to remove from system\n\n")
	print("Type: 'm' for main menu\n")
	print("Type: 'q' to quit the application\n\n")
	color.Unset()
	var programName, _ = input(">> ")

	trimInput := strings.TrimSpace(programName)

	if trimInput == "m" {
		return
	} else if trimInput == "q" {
		os.Exit(0)
	} else {
		cmd := exec.Command("flatpak", "uninstall", trimInput)
		out, err := cmd.CombinedOutput()
		if err != nil {
			removePak()
		}
		color.Set(color.FgHiRed)
		print("\n==========================================================================\n\n")
		fmt.Print(string(out), "\n\n")
		print("\n==========================================================================\n\n")
		color.Unset()
		removePak()
	}
}

//// TODO
/*
func optionsMenu() {
	var choice string
	print("\n| FlatFace Options |\n\n")
	print("\n1. Add Repository\n\n")

	choice, _ = input(">> ")

	if choice == "1" {

	}
}
*/
func syncRepo() {
	color.Set(color.FgHiMagenta)
	print("Syncing repo data...\n")
	color.Unset()
	cmd := exec.Command("flatpak", "update", "--appstream")

	out, err := cmd.CombinedOutput()

	if err != nil {
		log.Fatalf("cmd.Run() failed with %s\n", err)
	}
	color.Set(color.FgHiGreen)
	fmt.Print(string(out))
	color.Unset()
}

func checkRepo() {
	color.Set(color.FgHiYellow)
	print("\nAdding flathub repo if needed...\n")
	cmd := exec.Command("flatpak", "remote-add", "--if-not-exists", "flathub", "https://flathub.org/repo/flathub.flatpakrepo")
	out, err := cmd.CombinedOutput()
	syncRepo()
	if err != nil {
		log.Fatalf("cmd.Run() failed with %s\n", err)
	}
	fmt.Print(string(out))
}

func updatePak() {
	color.Set(color.FgHiYellow)
	print("Checking for app upgrades..\n")
	color.Unset()
	cmd := exec.Command("flatpak", "update", "-y")
	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatalf("cmd.Run() failed with %s\n", err)
	}
	color.Set(color.FgHiGreen)
	fmt.Print(string(out))
	color.Unset()
}
func mainMenu() {
	color.Set(color.FgHiCyan)
	print("\n\n| FlatFace v0.0.1a-4 |\n\n")
	var choice string

	print("[s] Search remote for flatpaks\n")
	print("[l] Install flatpaks from remote\n")
	print("[r] Remove local flatpaks\n")
	print("[l] List install flatpaks\n")
	print("[u] Update\n")
	print("[q] Quit\n\n")
	color.Unset()

	choice, _ = input(">> ")

	trimInput := strings.TrimSpace(choice)

	if trimInput == "s" {
		searchRepo()

	} else if trimInput == "i" {
		installPak()
	} else if trimInput == "r" {
		removePak()
	} else if trimInput == "l" {
		listPak()
	} else if trimInput == "u" {
		updatePak()
	} else if trimInput == "q" {
		os.Exit(0)
	} else {
		print("Unknown option")
	}

}

func main() {
	checkRepo()
	for {
		mainMenu()
	}
}
