function addNavItem(title, icon, route, navItems, key, testid, color = null) {
  if (!testid) {
    testid = route;
  }

  const o = {
    title,
    icon,
    route,
    navItems,
    key: key,
    testid: testid
  };
  if (color != null) {
    o["color"] = color;
  }
  o.navItems.forEach(z => {
    if (z.testid == null) {
      z.testid = z.route;
    }
  });

  window.$gz.store.commit("addNavItem", o);
}

function initNavPanel() {
  let key = 0;
  let sub = [];
  const licenseState = window.$gz.store.state.globalSettings.licenseStatus;
  const useInventory = window.$gz.store.state.globalSettings.useInventory;
  const licenseLockout = window.$gz.store.state.l;
  const isSu = window.$gz.store.getters.isSuperUser == true;

  /*Service = 1,
        NotService = 2,
        Customer = 3,
        HeadOffice = 4,        
        ServiceContractor = 5 */

  //########## OUTSIDE USERS GROUP (CUSTOMER / HEADOFFICE) ###
  if (window.$gz.store.getters.isCustomerUser == true) {
    //clear sublevel array
    sub = [];

    //Set homePage in store to customer csr for this user type
    let CustomerHomePageSet = false;

    //USER SETTINGS
    if (window.$gz.store.state.customerRights.userSettings == true) {
      sub.push({
        title: "UserSettings",
        icon: "$ayiUserCog",
        route: "/home-user-settings",
        key: key++
      });

      window.$gz.store.commit("setHomePage", "/home-user-settings");
      CustomerHomePageSet = true;
    }

    if (window.$gz.store.getters.canSubscribeToNotifications) {
      sub.push({
        title: "NotifySubscriptionList",
        icon: "$ayiBullhorn",
        route: "/home-notify-subscriptions",
        key: key++
      });

      window.$gz.store.commit("setHomePage", "/home-notify-subscriptions");
      CustomerHomePageSet = true;
    }

    //WORKORDERS subitem
    if (window.$gz.store.state.customerRights.wo == true) {
      sub.push({
        title: "WorkOrderList",
        icon: "$ayiTools",
        route: "/customer-workorders",
        key: key++
      });
      window.$gz.store.commit("setHomePage", "/customer-workorders");
      CustomerHomePageSet = true;
    }

    //CSR LIST subitem
    if (window.$gz.store.state.customerRights.csr == true) {
      sub.push({
        title: "CustomerServiceRequestList",
        icon: "$ayiConciergeBell",
        route: "/customer-csr",
        key: key++
      });

      window.$gz.store.commit("setHomePage", "/customer-csr");
      CustomerHomePageSet = true;
    }

    //** CUSTOMER LOGIN HOME (TOP)
    addNavItem("Home", "$ayiHome", undefined, sub, key++, "homecustomer");

    //last resort home page if nothing else kicked in
    if (!CustomerHomePageSet) {
      window.$gz.store.commit("setHomePage", "/no-features-available");
    }

    return;
  }

  //###### SUBCONTRACTORS ######
  if (window.$gz.store.getters.isSubContractorUser == true) {
    //clear sublevel array
    sub = [];

    //USER SETTINGS

    sub.push({
      title: "UserSettings",
      icon: "$ayiUserCog",
      route: "/home-user-settings",
      key: key++
    });

    //SCHEDULE (personal)
    sub.push({
      title: "Schedule",
      icon: "$ayiCalendarDay",
      route: "/home-schedule",
      key: key++
    });

    //** HOME (TOP)
    addNavItem("Home", "$ayiHome", undefined, sub, key++, "home");

    //set default home page
    window.$gz.store.commit("setHomePage", "/home-schedule");

    return;
  }

  //###### ALL INSIDE USERS FROM HERE DOWN ###############

  //###### EXPIRED LICENSE GROUP

  //Status  NONE, EXPIREDTRIAL, EXPIREDPURCHASE, REVOKED

  //So an expired purchased is a Rental type license and perpetual do not expire ever so this is kosher
  //we used to allow read only access when expired but this is more dramatic and we can always issue a one day license if they need it for something
  //and we're feeling generous so leaving as is for now
  //only show license and logout
  /*     public enum LicenseStatus
            {
                NONE = 0,
                ActiveTrial = 1,
                ExpiredTrial = 2,
                ActivePurchased = 3,
                ExpiredPurchased = 4,
                Revoked = 5
            } 
  */

  if (
    licenseState == 0 ||
    licenseState == 2 ||
    licenseState == 4 ||
    licenseState == 5
  ) {
    addNavItem(
      "HelpLicense",
      "$ayiTicket",
      "/adm-license",
      [],
      key++,
      "license"
    );

    //add some diagnostic ops features in case that's needed to resolve license issue
    sub = [];
    // LOGS
    if (window.$gz.role.canOpen(window.$gz.type.LogFile)) {
      sub.push({
        title: "ServerLog",
        icon: "$ayiHistory",
        route: "/ops-log",
        key: key++
      });
    }
    // OPS VIEW SERVER CONFIGURATION
    if (window.$gz.role.canOpen(window.$gz.type.GlobalOps)) {
      sub.push({
        title: "ViewServerConfiguration",
        icon: "$ayiInfoCircle",
        route: "/ops-view-configuration",
        key: key++
      });
    }

    // ** OPERATIONS (TOP)
    if (sub.length > 0) {
      addNavItem(
        "Operations",
        "$ayiServer",
        undefined,
        sub,
        key++,
        "operations"
      );
    }

    window.$gz.store.commit("setHomePage", "/adm-license");
    return;
  }

  //####### HOME GROUP
  if (!licenseLockout) {
    //DASHBOARD
    if (!isSu) {
      sub.push({
        title: "Dashboard",
        icon: "$ayiTachometer",
        route: "/home-dashboard",
        key: key++
      });

      //SEARCH
      sub.push({
        title: "Search",
        icon: "$ayiSearch",
        route: "/home-search",
        key: key++
      });

      //SCHEDULE (personal)
      sub.push({
        title: "Schedule",
        icon: "$ayiCalendarDay",
        route: "/home-schedule",
        key: key++
      });
    }

    //MEMOS
    sub.push({
      title: "MemoList",
      icon: "$ayiInbox",
      route: "/home-memos",
      key: key++
    });

    if (!isSu) {
      //REMINDERS
      sub.push({
        title: "ReminderList",
        icon: "$ayiStickyNote",
        route: "/home-reminders",
        key: key++
      });

      //REVIEWS
      sub.push({
        title: "ReviewList",
        icon: "$ayiCalendarCheck",
        route: "/home-reviews",
        key: key++
      });
    }
    //USER SETTINGS
    sub.push({
      title: "UserSettings",
      icon: "$ayiUserCog",
      route: "/home-user-settings",
      key: key++
    });
    if (!isSu) {
      //USER NOTIFICATION SUBSCRIPTIONS
      sub.push({
        title: "NotifySubscriptionList",
        icon: "$ayiBullhorn",
        route: "/home-notify-subscriptions",
        key: key++
      });
    }
    //HISTORY / MRU / ACTIVITY (personal)
    sub.push({
      title: "History",
      icon: "$ayiHistory",
      route: `/history/3/${window.$gz.store.state.userId}/true`,
      key: key++,
      testid: "/home-history"
    });

    //HOME
    if (sub.length > 0) {
      //Set homePage in store to dashboard
      window.$gz.store.commit("setHomePage", "/home-dashboard");
      addNavItem("Home", "$ayiHome", undefined, sub, key++, "home");
    }

    //######### CUSTOMER GROUP
    if (window.$gz.role.canOpen(window.$gz.type.Customer) && !isSu) {
      //these all require Customer rights so all in the same block

      //clear sublevel array
      sub = [];

      //CUSTOMERS subitem
      sub.push({
        title: "CustomerList",
        icon: "$ayiAddressCard",
        route: "/cust-customers",
        key: key++
      });

      //HEAD OFFICES subitem
      sub.push({
        title: "HeadOfficeList",
        icon: "$ayiSitemap",
        route: "/cust-head-offices",
        key: key++
      });

      //Customer / Headoffice Users subitem
      sub.push({
        title: "Contacts",
        icon: "$ayiUsers",
        route: "/cust-users",
        key: key++
      });

      sub.push({
        title: "CustomerNotifySubscriptionList",
        icon: "$ayiBullhorn",
        route: "/cust-notify-subscriptions",
        key: key++
      });

      // ** CUSTOMER (TOP)
      addNavItem(
        "CustomerList",
        "$ayiAddressBook",
        undefined,
        sub,
        key++,
        "customer"
      );
    }

    //#######  SERVICE GROUP

    sub = [];

    //SCHEDULE (service)
    if (
      window.$gz.role.canOpen(window.$gz.type.WorkOrder) ||
      window.$gz.role.canOpen(window.$gz.type.Quote) ||
      window.$gz.role.canOpen(window.$gz.type.PM)
    ) {
      sub.push({
        title: "Schedule",
        icon: "$ayiCalendarAlt",
        route: "/svc-schedule",
        key: key++
      });
    }

    //WORKORDERS LIST (was service workorders)
    if (window.$gz.role.canOpen(window.$gz.type.WorkOrder)) {
      sub.push({
        title: "WorkOrderList",
        icon: "$ayiTools",
        route: "/svc-workorders",
        key: key++
      });
    }

    //QUOTE LIST
    if (window.$gz.role.canOpen(window.$gz.type.Quote)) {
      sub.push({
        title: "QuoteList",
        icon: "$ayiPencilAlt",
        route: "/svc-quotes",
        key: key++
      });
    }

    //PM LIST
    if (window.$gz.role.canOpen(window.$gz.type.PM)) {
      sub.push({
        title: "PMList",
        icon: "$ayiBusinessTime",
        route: "/svc-pms",
        key: key++
      });
    }

    //UNITS subitem
    if (window.$gz.role.canOpen(window.$gz.type.Unit)) {
      sub.push({
        title: "UnitList",
        icon: "$ayiFan",
        route: "/svc-units",
        key: key++
      });
    }

    //LOANERS subitem
    if (window.$gz.role.canOpen(window.$gz.type.LoanUnit)) {
      sub.push({
        title: "LoanUnitList",
        icon: "$ayiPlug",
        route: "/svc-loaners",
        key: key++
      });
    }

    //PROJECTS subitem
    if (window.$gz.role.canOpen(window.$gz.type.Project)) {
      sub.push({
        title: "ProjectList",
        icon: "$ayiProjectDiagram",
        route: "/svc-projects",
        key: key++
      });
    }

    //CUSTOMER SERVICE REQUESTS subitem
    if (window.$gz.role.canOpen(window.$gz.type.CustomerServiceRequest)) {
      sub.push({
        title: "CustomerServiceRequestList",
        icon: "$ayiConciergeBell",
        route: "/svc-csr",
        key: key++
      });
    }

    //**** Service (TOP GROUP)
    if (
      sub.length > 0 &&
      !isSu &&
      !window.$gz.role.hasRole([
        window.$gz.role.AUTHORIZATION_ROLES.TechRestricted
      ])
    ) {
      addNavItem("Service", "$ayiToolbox", undefined, sub, key++, "service");
    }

    //######### INVENTORY GROUP

    //clear sublevel array
    sub = [];

    //PARTS (part list)
    if (window.$gz.role.canOpen(window.$gz.type.Part)) {
      sub.push({
        title: "PartList",
        icon: "$ayiBoxes",
        route: "/inv-parts",
        key: key++
      });
    }

    //PURCHASE ORDERS / PART REQUESTS
    if (
      useInventory &&
      window.$gz.role.canOpen(window.$gz.type.PurchaseOrder)
    ) {
      sub.push({
        title: "InventoryPurchaseOrders",
        icon: "$ayiTruckLoading",
        route: "/inv-purchase-orders",
        key: key++
      });

      sub.push({
        title: "WorkOrderItemPartRequestList",
        icon: "$ayiParachuteBox",
        route: "/inv-part-requests",
        key: key++
      });
    }

    //INVENTORY
    if (
      useInventory &&
      window.$gz.role.canOpen(window.$gz.type.PartInventory)
    ) {
      sub.push({
        title: "PartInventoryDataList",
        icon: "$ayiPallet",
        route: "/inv-part-inventory",
        key: key++
      });
    }

    //INVENTORY TRANSACTIONS
    if (
      useInventory &&
      window.$gz.role.canOpen(window.$gz.type.PartInventory)
    ) {
      sub.push({
        title: "PartInventoryTransactionList",
        icon: "$ayiPeopleCarry",
        route: "/inv-part-inventory-transactions",
        key: key++
      });
    }

    //PART ASSEMBLIES
    if (window.$gz.role.canOpen(window.$gz.type.PartAssembly)) {
      sub.push({
        title: "PartAssemblyList",
        icon: "$ayiObjectGroup",
        route: "/inv-part-assemblies",
        key: key++
      });
    }

    //WAREHOUSES
    if (
      useInventory &&
      window.$gz.role.canOpen(window.$gz.type.PartWarehouse)
    ) {
      sub.push({
        title: "PartWarehouseList",
        icon: "$ayiWarehouse",
        route: "/inv-part-warehouses",
        key: key++
      });
    }

    //**** INVENTORY (TOP GROUP)
    if (sub.length > 0 && !isSu) {
      addNavItem("Inventory", "$ayiDolly", undefined, sub, key++, "inventory");
    }

    //######### VENDORS (TOP GROUP)
    if (window.$gz.role.canOpen(window.$gz.type.Vendor) && !isSu) {
      addNavItem("VendorList", "$ayiStore", "/vendors", [], key++, "vendor");
    }

    //******************  ACCOUNTING

    sub = [];

    //SERVICE CONTRACTS subitem
    if (window.$gz.role.canOpen(window.$gz.type.Contract)) {
      sub.push({
        title: "ContractList",
        icon: "$ayiFileContract",
        route: "/svc-contracts",
        key: key++
      });
    }
    // //SERVICE BANK
    // if (window.$gz.role.canOpen(window.$gz.type.ServiceBank)) {
    //   sub.push({
    //     title: "ServiceBankList",
    //     icon: "$ayiCarBattery",
    //     route: "/acc-service-banks",
    //     key: key++
    //   });
    // }

    //SERVICE RATES
    if (window.$gz.role.canOpen(window.$gz.type.ServiceRate)) {
      sub.push({
        title: "ServiceRateList",
        icon: "$ayiCalculator",
        route: "/acc-service-rates",
        key: key++
      });
    }

    //TRAVEL RATES
    if (window.$gz.role.canOpen(window.$gz.type.TravelRate)) {
      sub.push({
        title: "TravelRateList",
        icon: "$ayiCalculator",
        route: "/acc-travel-rates",
        key: key++
      });
    }

    if (window.$gz.role.canOpen(window.$gz.type.TaxCode)) {
      sub.push({
        title: "TaxCodeList",
        icon: "$ayiPercent",
        route: "/acc-tax-codes",
        key: key++
      });
    }

    // ** ACCOUNTING (TOP)
    if (sub.length > 0 && !isSu) {
      addNavItem(
        "Accounting",
        "$ayiCoins",
        undefined,
        sub,
        key++,
        "accounting"
      );
    }
  } //end of licenseLockout check group
  //#############  ADMINISTRATION

  //clear sublevel array
  sub = [];

  // GLOBAL SETTINGS
  if (window.$gz.role.canOpen(window.$gz.type.Global)) {
    sub.push({
      title: "AdministrationGlobalSettings",
      icon: "$ayiCogs",
      route: "/adm-global-settings",
      key: key++
    });
  }

  // LICENSE
  //special work around here as Integration addition requires all roles to read license but that exposes it in the UI so instead of checking by rights
  //sb limited to BizAdmin full only
  //if (window.$gz.role.canOpen(window.$gz.type.License)) {
  if (window.$gz.role.hasRole([window.$gz.role.AUTHORIZATION_ROLES.BizAdmin])) {
    sub.push({
      title: "HelpLicense",
      icon: "$ayiTicket",
      route: "/adm-license",
      key: key++
    });
  }

  // USERS
  if (window.$gz.role.canOpen(window.$gz.type.User)) {
    sub.push({
      title: "UserList",
      icon: "$ayiUsers",
      route: "/adm-users",
      key: key++
    });
  }

  //TRANSLATION
  if (!licenseLockout && window.$gz.role.canOpen(window.$gz.type.Translation)) {
    sub.push({
      title: "TranslationList",
      icon: "$ayiLanguage",
      route: "/adm-translations",
      key: key++
    });
  }

  //REPORT TEMPLATES
  if (!licenseLockout && window.$gz.role.canChange(window.$gz.type.Report)) {
    sub.push({
      title: "ReportList",
      icon: "$ayiThList",
      route: "/adm-report-templates",
      key: key++
    });
  }

  //FILES IN DATABASE
  if (
    !licenseLockout &&
    window.$gz.role.canOpen(window.$gz.type.FileAttachment)
  ) {
    sub.push({
      title: "Attachments",
      icon: "$ayiPaperclip",
      route: "/adm-attachments",
      key: key++
    });
  }

  //EVENT LOG / HISTORY
  if (!licenseLockout && window.$gz.role.canOpen(window.$gz.type.Global)) {
    //not really an appropriate object here just guessing
    sub.push({
      title: "History",
      icon: "$ayiHistory",
      route: "/adm-history",
      key: key++
    });
  }

  //IMPORT
  if (!licenseLockout && window.$gz.role.canOpen(window.$gz.type.Global)) {
    //again, not really an appropriate object type
    sub.push({
      title: "Import",
      icon: "$ayiFileImport",
      route: "/adm-import",
      key: key++
    });
  }

  //INTEGRATION
  //decision here is that only teh biz admin can *control* or remove an integration
  //even though all full role inside users can create or edit integrations (just not through the AyaNova user interface)
  //this is required to support integrations made for various roles like inventory accounting etc
  if (!licenseLockout && window.$gz.role.canOpen(window.$gz.type.Global)) {
    sub.push({
      title: "IntegrationList",
      icon: "$ayiCampground",
      route: "/adm-integrations",
      key: key++
    });
  }

  // ** ADMINISTRATION (TOP)
  if (sub.length > 0) {
    addNavItem(
      "Administration",
      "$ayiUserTie",
      undefined,
      sub,
      key++,
      "administration"
    );
  }

  //############ OPERATIONS

  //clear sublevel array
  sub = [];

  // BACKUP
  if (window.$gz.role.canOpen(window.$gz.type.Backup)) {
    sub.push({
      title: "Backup",
      icon: "$ayiFileArchive",
      route: "/ops-backup",
      key: key++
    });
  }

  // SERVER STATE
  if (
    !licenseLockout &&
    window.$gz.role.canChange(window.$gz.type.ServerState)
  ) {
    sub.push({
      title: "ServerState",
      icon: "$ayiDoorOpen",
      route: "/ops-server-state",
      key: key++
    });
  }

  // JOBS
  if (!licenseLockout && window.$gz.role.canOpen(window.$gz.type.ServerJob)) {
    sub.push({
      title: "ServerJobs",
      icon: "$ayiRobot",
      route: "/ops-jobs",
      key: key++
    });
  }

  // LOGS
  if (window.$gz.role.canOpen(window.$gz.type.LogFile)) {
    sub.push({
      title: "ServerLog",
      icon: "$ayiHistory",
      route: "/ops-log",
      key: key++
    });
  }

  //METRICS
  if (
    !licenseLockout &&
    window.$gz.role.canOpen(window.$gz.type.ServerMetrics)
  ) {
    sub.push({
      title: "ServerMetrics",
      icon: "$ayiFileMedicalAlt",
      route: "/ops-metrics",
      key: key++
    });

    // //PROFILE
    // //metrics rights
    // sub.push({
    //   title: "ServerProfiler",
    //   icon: "$ayiBinoculars",
    //   route: "/ops-profile",
    //   key: key++
    // });
  }

  //NOTIFICATION CONFIG AND HISTORY
  if (
    !licenseLockout &&
    window.$gz.role.canOpen(window.$gz.type.OpsNotificationSettings)
  ) {
    sub.push({
      title: "OpsNotificationSettings",
      icon: "$ayiBullhorn",
      route: "/ops-notification-settings",
      key: key++
    });
  }

  if (
    !licenseLockout &&
    window.$gz.role.canOpen(window.$gz.type.OpsNotificationSettings)
  ) {
    sub.push({
      title: "NotificationDeliveryLog",
      icon: "$ayiHistory",
      route: "/ops-notify-log",
      key: key++
    });
  }

  if (
    !licenseLockout &&
    window.$gz.role.canOpen(window.$gz.type.OpsNotificationSettings)
  ) {
    sub.push({
      title: "NotificationCustomerDeliveryLog",
      icon: "$ayiHistory",
      route: "/ops-customer-notify-log",
      key: key++
    });
  }

  // OPS VIEW SERVER CONFIGURATION
  if (window.$gz.role.canOpen(window.$gz.type.GlobalOps)) {
    sub.push({
      title: "ViewServerConfiguration",
      icon: "$ayiInfoCircle",
      route: "/ops-view-configuration",
      key: key++
    });
  }

  // ** OPERATIONS (TOP)
  if (sub.length > 0) {
    addNavItem("Operations", "$ayiServer", undefined, sub, key++, "operations");
  }

  //*** EVALUATION active trial license should always go to evaluation as home page
  //as long as they are a normal User type and not a subcontractor type
  if (
    (licenseState == 1) &
    (window.$gz.store.getters.isSubContractorUser == false)
  ) {
    addNavItem(
      "Evaluate",
      "$ayiRocket",
      "/ay-evaluate",
      [],
      key++,
      "evaluate",
      "secondary"
    );
    window.$gz.store.commit("setHomePage", "/ay-evaluate");
  }

  if (licenseLockout) {
    window.$gz.store.commit("setHomePage", "/adm-license");
  }
}

async function getUserOptions() {
  try {
    const res = await window.$gz.api.get(
      "user-option/" + window.$gz.store.state.userId
    );

    if (res.error) {
      //In a form this would trigger a bunch of validation or error display code but for here and now:
      //convert error to human readable string for display and popup a notification to user
      const msg = window.$gz.api.apiErrorToHumanString(res.error);
      window.$gz.store.commit(
        "logItem",
        "Initialize::() fetch useroptions -> error" + msg
      );
      window.$gz.eventBus.$emit("notify-error", msg);
    } else {
      //Check if overrides and use them here
      //or else use browser defaults

      const l = {
        languageOverride: null,
        timeZoneOverride: null,
        currencyName: null,
        hour12: true,
        //uiColor: "#000000ff",
        emailAddress: null,
        mapUrlTemplate: null
      };

      l.languageOverride = res.data.languageOverride;
      l.timeZoneOverride = res.data.timeZoneOverride;

      //No browser setting for this so meh
      l.currencyName = res.data.currencyName;

      if (res.data.hour12 != null) {
        l.hour12 = res.data.hour12;
      }

      //  l.uiColor = res.data.uiColor || "#000000ff";
      l.emailAddress = res.data.emailAddress || null;

      l.mapUrlTemplate = res.data.mapUrlTemplate || null;

      window.$gz.store.commit("setUserOptions", l);
    }
  } catch (error) {
    window.$gz.store.commit(
      "logItem",
      "Initialize::() fetch useroptions -> error" + error
    );
    throw new Error(window.$gz.errorHandler.errorToString(error));
  }
}

/////////////////////////////////////
// Initialize the app
// on change of authentication status
export default function initialize() {
  // eslint-disable-next-line no-async-promise-executor
  return new Promise(async function(resolve, reject) {
    if (!window.$gz.store.state.authenticated) {
      throw new Error("initialize: Error, called but user not authenticated!");
    }
    try {
      await window.$gz.translation.cacheTranslations(
        window.$gz.translation.coreKeys
      );
      initNavPanel();
      await getUserOptions();

      //check for known password and a purchased licensed mode
      if (
        window.$gz.store.state.knownPassword &&
        window.$gz.store.state.globalSettings.licenseStatus == 3 //ActivePurchased = 3, (only this, if expired this prevents user from fixing license so don't do this if expired)
      ) {
        window.$gz.store.commit("setHomePage", "/home-password");
      }

      resolve();
    } catch (err) {
      reject(err);
    }
  });
}
