package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/fatih/color"
	termbox "github.com/nsf/termbox-go"
)

var elevatorFloor int
var floorInv [][]string
var componentRegistry []string
var cursorPosX, cursorPosY int
var selectItems []string

// This code requires oxford commas in the input
func main() {
	input := stdinToStringSlice()
	for i := range input {
		listIdx := strings.Index(input[i], "a ")
		if listIdx == -1 {
			floorInv = append(floorInv, []string{})
			continue
		}
		input[i] = input[i][listIdx:]
		floorInv = append(floorInv, strings.Split(input[i], ", "))
	}
	for i := range floorInv {
		for j := range floorInv[i] {
			tp := "G"
			if strings.Contains(floorInv[i][j], "microchip") {
				tp = "M"
			}
			floorInv[i][j] = strings.TrimPrefix(floorInv[i][j], "a ")
			floorInv[i][j] = strings.TrimPrefix(floorInv[i][j], "and a ")
			ele := strings.ToUpper(floorInv[i][j][:2])
			floorInv[i][j] = ele + ":" + tp
			componentRegistry = append(componentRegistry, floorInv[i][j])
		}
	}

	err := termbox.Init()
	if err != nil {
		fmt.Println("Error initializing termbox")
		os.Exit(1)
	}
	defer termbox.Close()

	eventQueue := make(chan termbox.Event)
	go func() {
		for {
			eventQueue <- termbox.PollEvent()
		}
	}()

	PrintScreen()
	var doQuit bool
	for {
		select {
		case ev := <-eventQueue:
			if ev.Type == termbox.EventKey {
				switch {
				case ev.Key == termbox.KeyArrowLeft:
					if cursorPosX > 0 {
						cursorPosX--
					}
				case ev.Key == termbox.KeyArrowRight:
					if cursorPosX < len(componentRegistry)-1 {
						cursorPosX++
					}
				case ev.Ch == 'q':
					doQuit = true
				}
			}
			ClearScreen()
			PrintScreen()
		}
		if doQuit {
			break
		}
	}
	//fmt.Println("Registered Components: ", componentRegistry)

	// a microchip without it's generator cannot be on the same floor
	//		as a different microchip that _does_ have it's generator

	// Look at what we have on the lowest floor with items
	// For each microchip, find it's generator
	//	if it's on this floor, take them both up a floor
	// If we have microchips, see where their generators are
	// If they are with us, take both and move up
	// If they are one floor above,
}

func SelectItem() error {
	return nil
}

func FloorHasComponent(flr int, cmp string) bool {
	for i := range floorInv[flr] {
		if floorInv[flr][i] == cmp {
			return true
		}
	}
	return false
}

func MoveElevator(dir int, take []string) error {
	if len(take) < 1 || len(take) > 2 {
		return errors.New("Error tried to move with invalid number of items: " + itoa(len(take)))
	}
	// Are the requested items on the current floor?
	// If so, move them to the floor we're going to
	for j := range take {
		if FloorHasComponent(elevatorFloor, take[j]) {
			// TODO: Move the component
			floorInv[elevatorFloor+dir] = append(floorInv[elevatorFloor+dir], take[j])
		} else {
			return errors.New("Elevator tried to take " + take[j] + " but it's not on floor " + itoa(elevatorFloor+1))
		}
	}
	return nil
}

func ClearScreen() {
	fmt.Print("\033[H\033[2J")
}

func PrintScreen() {
	c := color.New(color.FgCyan)
	w := color.New(color.FgWhite)
	g := color.New(color.FgGreen)
	g.Add(color.Bold)
	for i := len(floorInv); i > 0; i-- {
		c.Printf("F%d ", i)
		if elevatorFloor == i-1 {
			c.Print("E ")
		} else {
			w.Print(". ")
		}
		for cr := range componentRegistry {
			out := ".    "
			for j := range floorInv[i-1] {
				if floorInv[i-1][j] == componentRegistry[cr] {
					out = componentRegistry[cr] + " "
					break
				}
			}
			if elevatorFloor == i-1 && cursorPosX == cr {
				g.Print(out)
			} else {
				w.Print(out)
			}
		}
		w.Println("")
	}
	w.Println("")
}

func stdinToStringSlice() []string {
	var input []string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = append(input, scanner.Text())
	}
	return input
}

func itoa(i int) string {
	return strconv.Itoa(i)
}
