package parser

import (
	"database/sql"
	"fmt"
)

type Row struct {
	MenuId    int
	Menu      sql.NullString
	Submenu   sql.NullString
	Item      sql.NullString
	Parent    int
	Child     int
	Position  int
	ChildType string
	MenuRoot  bool
	ItemRoot  bool
}

type Menu struct {
	Id       int
	children []MenuNode
}

type MenuItem struct {
	Id   int
	Name string
}

func (menu Menu) Children() []MenuNode {
	return menu.children
}

func (menu Menu) SetChildren(children []MenuNode) {
	menu.children = children
}

func (menuItem MenuItem) Children() []MenuNode {
	return []MenuNode{}
}
func (menuItem MenuItem) SetChildren(children []MenuNode) {
}

type MenuNode interface {
	Children() []MenuNode
	SetChildren([]MenuNode)
}

func Parse(rows []Row) []Menu {
	rootMenus := make([]*Menu, 0, len(rows))
	menus := make(map[int][]*Menu)
	children := make(map[int][]MenuNode)
	for _, row := range rows {
		if row.ChildType == "Menu" {
			if row.MenuRoot == true {
				rootMenus = append(rootMenus, &Menu{Id: row.Child})
			} else {
				index_menu := menus[row.Parent]
				index_menu = append(index_menu, &Menu{Id: row.Child})
				menus[row.Parent] = index_menu
			}

		} else if row.ChildType == "MenuItem" {
			child_index := children[row.Parent]
			child_index = append(child_index, MenuItem{Id: row.Child, Name: row.Item.String})
			children[row.Parent] = child_index
		}
	}

	fmt.Println("Rootmenus", rootMenus)
	fmt.Println("Menus", menus)
	fmt.Println("Children", children)
	for i := range rootMenus {
		menu := rootMenus[i]
		menu_submenus := menus[menu.Id]
		nodes_submenus := make([]MenuNode, len(menu_submenus))
		for i, v := range menu_submenus {
			nodes_submenus[i] = MenuNode(v)
		}
		menu.children = append(menu.children, nodes_submenus...)

		menu_children := children[menu.Id]
		nodes_children := make([]MenuNode, len(menu_children))
		for i, v := range menu_children {
			nodes_children[i] = MenuNode(v)
		}
		fmt.Println("Nodes children", nodes_children)
		menu.children = append(menu.children, nodes_children...)
		fmt.Println(menu.children)
	}

	for i := range menus {
		m := menus[i]
		for i := range m {
			menu_ref := m[i]
			menu_children := children[menu_ref.Id]
			nodes_children := make([]MenuNode, len(menu_children))
			for i, v := range menu_children {
				nodes_children[i] = MenuNode(v)
			}
			menu_ref.children = append(menu_ref.children, nodes_children...)
		}
	}
	fmt.Println(rootMenus[0].children)
	result := make([]Menu, 0, len(rootMenus))
	for _, elem := range rootMenus {
		result = append(result, *elem)
	}
	return result
}