import { describe, test, expect } from 'vitest'
import {RuntimeConfig} from "@nuxt/schema";
import {AnyAbility} from "@casl/ability/dist/types";
import {AccessProfile, organizationState} from "~/types/interfaces";
import MainMenuBuilder from "~/services/layout/menuBuilder/mainMenuBuilder";
import {MenuGroup} from "~/types/layout";
import {MENU_LINK_TYPE} from "~/types/enum/layout";
import AbstractMenuBuilder from "~/services/layout/menuBuilder/abstractMenuBuilder";
import AccessMenuBuilder from "~/services/layout/menuBuilder/accessMenuBuilder";
import AgendaMenuBuilder from "~/services/layout/menuBuilder/agendaMenuBuilder";
import EquipmentMenuBuilder from "~/services/layout/menuBuilder/equipmentMenuBuilder";
import EducationalMenuBuilder from "~/services/layout/menuBuilder/educationalMenuBuilder";
import BillingMenuBuilder from "~/services/layout/menuBuilder/billingMenuBuilder";
import CommunicationMenuBuilder from "~/services/layout/menuBuilder/communicationMenuBuilder";
import DonorsMenuBuilder from "~/services/layout/menuBuilder/donorsMenuBuilder";
import MedalsMenuBuilder from "~/services/layout/menuBuilder/medalsMenuBuilder";
import WebsiteAdminMenuBuilder from "~/services/layout/menuBuilder/websiteAdminMenuBuilder";
import CotisationsMenuBuilder from "~/services/layout/menuBuilder/cotisationsMenuBuilder";
import StatsMenuBuilder from "~/services/layout/menuBuilder/statsMenuBuilder";
import Admin2iosMenuBuilder from "~/services/layout/menuBuilder/admin2iosMenuBuilder";

let runtimeConfig: RuntimeConfig
let ability: AnyAbility
let organizationProfile: organizationState
let accessProfile: AccessProfile
let menuBuilder: MainMenuBuilder

beforeEach(()=> {
    runtimeConfig = vi.fn() as any as RuntimeConfig
    ability = vi.fn() as any as AnyAbility
    organizationProfile = vi.fn() as any as organizationState
    accessProfile = vi.fn() as any as AccessProfile

    runtimeConfig.baseUrlAdminLegacy = 'https://mydomain.com/'

    menuBuilder = new MainMenuBuilder(runtimeConfig, ability, organizationProfile, accessProfile)
})

describe('getMenuName', () => {
    test('validate name', () => {
        expect(menuBuilder.getMenuName()).toEqual("Main")
    })
})

describe('build', () => {
    test('return all menus', () => {
        // @ts-ignore
        menuBuilder.buildSubmenu = vi.fn((menuBuilder: typeof AbstractMenuBuilder): MenuGroup => {
            return { label: 'foo' }
        })

        const result = menuBuilder.build() as MenuGroup

        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(AccessMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(AgendaMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(EquipmentMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(EducationalMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(BillingMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(CommunicationMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(DonorsMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(MedalsMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(WebsiteAdminMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(CotisationsMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(StatsMenuBuilder)
        // @ts-ignore
        expect(menuBuilder.buildSubmenu).toBeCalledWith(Admin2iosMenuBuilder)

        expect(result.label).toEqual('main')
        expect(result.icon).toEqual(undefined)
        expect((result.children ?? []).length).toEqual(12)
    })

    test('return a single group', () => {
        // @ts-ignore
        menuBuilder.buildSubmenu = vi.fn((menuBuilder: typeof AbstractMenuBuilder): MenuGroup | null => {
            if (menuBuilder.menuName === 'Access') {
                return { label: 'submenu', children: [
                        {label: 'item1', type: MENU_LINK_TYPE.INTERNAL, active: true},
                        {label: 'item2', type: MENU_LINK_TYPE.INTERNAL, active: true},
                        {label: 'item3', type: MENU_LINK_TYPE.INTERNAL, active: true}
                    ] }
            }
            return  null
        })

        const result = menuBuilder.build() as MenuGroup

        expect(result.label).toEqual('submenu')
        expect((result.children ?? []).length).toEqual(3)
    })

    test('return null', () => {
        // @ts-ignore
        menuBuilder.buildSubmenu = vi.fn((menuBuilder: typeof AbstractMenuBuilder): MenuGroup | null => {
            return  null
        })

        const result = menuBuilder.build() as MenuGroup

        expect(result).toEqual(null)
    })
})
