import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';

import { MenuItem } from 'primeng/primeng';

import { environment } from './../../../environments/environment';

import { ApiService } from './api.service';
import { ConfigService } from './config.service';
import { UserService } from './user.service';
import { UtilsService } from './utils.service';


@Injectable()
export class MenuService {

    private menu: any;

    menuUpdated     =   new Subject<any>();
    badgeUpdated    =   new Subject<any>();

    constructor(
        private apiService: ApiService,
        private configService: ConfigService,
        private userService: UserService,
        private utilsService: UtilsService
    ) {
        this.badgeUpdated.subscribe(
            (data) => {
                if(this.menu && data.Tag && data.Badge !== undefined) {
                    if(this.menu.mainMenu) {
                        this.updateMenuForTag(this.menu.mainMenu, data.Tag, data.Badge);
                    }

                    if(this.menu.topMenu) {
                        this.updateMenuForTag(this.menu.topMenu, data.Tag, data.Badge);
                    }
                    this.menuUpdated.next(this.utilsService.cloneObject(this.menu));
                }
            }
        )
    }

    private updateMenuForTag(menuItems: any[], tag: string, badge: string) {
        menuItems.forEach(menu => {
            if(menu.Tag && menu.Tag == tag) {
                menu.Badge  =   badge;
            }
        });
    }

    reloadMenuData(subscriptions: Array<Subscription>) {
        let url = "svc/Menu";
        let param = {
            "environment": environment.envName
        }

        subscriptions.push(this.apiService.post(url, param).subscribe(
            (data) => {
                if (data.result === this.configService.settings.status.success) {

                    var _menu: any   =   {};

                    _menu.mainMenu  =   (data.main ? this.recursiveMenuData(data.main.Children) : []);
                    _menu.topMenu   =   (data.updatedTopTop ? this.recursiveMenuData(data.updatedTopTop.Children) : []);

                    subscriptions.push(this.userService.reloadUserDetails().subscribe(
                        (userData) => {
                            let userMenu: MenuItem = {
                                icon: 'account_circle',
                                label: this.userService.getFullName(),
                                items: _menu.topMenu,
                                styleClass: 'user-menu'
                            };
                            _menu.mainMenu.push(userMenu);
                            this.menuUpdated.next(this.utilsService.cloneObject(_menu));

                            this.menu   =   _menu;
                        }
                    ));
                }
            }
        ));
    }

    recursiveMenuData(menu) {
        if (menu) {
            for (let i = 0; i < menu.length; i++) {
                if (menu[i].Description !== undefined) {
                    menu[i].label = menu[i].Description;
                    delete menu[i].Description;
                }
                
                if (menu[i].Tag) {
                    menu[i].id = menu[i].Tag.replace('.', '_');
                    delete menu[i].Tag;
                } else {
                    menu[i].id = 'MenuItem_' + (menu.id || '') + i;
                }

                if (menu[i].RouterLink !== undefined) {
                    menu[i].routerLink = menu[i].RouterLink;
                }
                else if (menu[i].Link !== undefined) {
                    menu[i].url = menu[i].Link;
                    delete menu[i].Link;
                }

                if (menu[i].Type !== undefined) {
                    delete menu[i].Type;
                }

                if (menu[i].AdditionalAttributes !== undefined) {
                    delete menu[i].AdditionalAttributes;
                }

                if (this.configService.settings.showMenuIcon) {
                    if (menu[i].MenuIcon) {
                        menu[i].icon = menu[i].MenuIcon;
                    } else if (this.configService.settings.defaultMenuIcon) {
                        menu[i].icon = this.configService.settings.defaultMenuIcon;
                    }
                }

                if (menu[i].Children !== undefined) {
                    menu[i].items = menu[i].Children;
                    delete menu[i].Children;
                    this.recursiveMenuData(menu[i].items);
                }
            }
            return menu;
        }
        return [];
    }
}