package service

import (
	"context"
	"gadmin/config"
	"gadmin/internal/admin/forms"
	"gadmin/internal/gorm/model"
	"gadmin/internal/gorm/query"
	"github.com/sirupsen/logrus"
	"os"
	"sort"
)

var Menu = NewAMenu()

type aMenu struct{}

func NewAMenu() *aMenu {
	return &aMenu{}
}

func (s *aMenu) GetMenuList() ([]*forms.Menu, error) {
	q := query.Use(config.DB).AdminMenu
	m := q.WithContext(context.Background())
	m = m.Where(q.Disable.Eq(0)).Order(q.Sort)
	if os.Getenv("ADMIN_IS_LOCAL") != "1" {
		m = m.Where(q.LocalShow.Eq(0))
	}
	menus, err := m.Find()
	if err != nil {
		logrus.Error(err)
		return nil, err
	}
	retMenus := handleMenus(menus)
	return retMenus, nil
}

func handleMenus(menus []*model.AdminMenu) []*forms.Menu {
	menuMap := make(map[int32]*forms.Menu, 0)
	for _, menu := range menus {
		item := &forms.Menu{
			Id:        menu.ID,
			Component: menu.Component,
			Meta: &forms.MenuMeta{
				Icon:       menu.Icon,
				Sort:       menu.Sort,
				Title:      menu.Title,
				Hidden:     menu.Hidden == 1,
				ActiveMenu: menu.ActiveMenu,
				IsRoot:     menu.IsRoot == 1,
			},
			Name:     menu.Name,
			Path:     menu.Path,
			Redirect: menu.Redirect,
			Children: []*forms.Menu{},
		}

		if menu.ParentID == 0 {
			if _, ok := menuMap[menu.ID]; ok {
				menuMap[menu.ID].Id = menu.ID
				menuMap[menu.ID].Component = menu.Component
				menuMap[menu.ID].Meta = item.Meta
				menuMap[menu.ID].Name = menu.Name
				menuMap[menu.ID].Path = menu.Path
				menuMap[menu.ID].Redirect = menu.Redirect
			} else {
				menuMap[menu.ID] = item
			}
		} else {
			if _, ok := menuMap[menu.ParentID]; ok {
				menuMap[menu.ParentID].Children = append(menuMap[menu.ParentID].Children, item)
			} else {
				menuMap[menu.ParentID] = &forms.Menu{
					Id:   menu.ParentID,
					Meta: &forms.MenuMeta{},
					Children: []*forms.Menu{
						item,
					},
				}
			}
		}
	}
	retMenus := make([]*forms.Menu, 0, len(menuMap))
	for _, menu := range menuMap {
		retMenus = append(retMenus, menu)
	}
	sort.Slice(retMenus, func(i, j int) bool {
		return retMenus[i].Meta.Sort < retMenus[j].Meta.Sort
	})
	return retMenus
}
