import React from "react";

import { shallow, mount } from "enzyme";

import moment from "moment";

import toDiffableHtml from "diffable-html";

import { AlertStore, NewUnappliedFilter } from "Stores/AlertStore";
import { Settings } from "Stores/Settings";
import { SilenceFormStore } from "Stores/SilenceFormStore";
import { NavBar } from ".";

let alertStore;
let settingsStore;
let silenceFormStore;

beforeEach(() => {
  alertStore = new AlertStore([]);
  settingsStore = new Settings();
  silenceFormStore = new SilenceFormStore();
  // fix startsAt & endsAt dates so they don't change between tests
  silenceFormStore.data.startsAt = moment([2018, 1, 30, 10, 25, 50]).utc();
  silenceFormStore.data.endsAt = moment([2018, 1, 30, 11, 25, 50]).utc();
});

const RenderNavbar = () => {
  return shallow(
    <NavBar
      alertStore={alertStore}
      settingsStore={settingsStore}
      silenceFormStore={silenceFormStore}
    />
  ).find(".container");
};

const MountedNavbar = () => {
  return mount(
    <NavBar
      alertStore={alertStore}
      settingsStore={settingsStore}
      silenceFormStore={silenceFormStore}
    />
  );
};

const ValidateNavClass = (totalFilters, expectedClass) => {
  for (let i = 0; i < totalFilters; i++) {
    alertStore.filters.values.push(NewUnappliedFilter(`foo=${i}`));
  }
  const tree = RenderNavbar();
  const nav = tree.find(".navbar-nav");
  expect(nav.props().className.split(" ")).toContain(expectedClass);
};

describe("<NavBar />", () => {
  it("navbar-brand shows 15 alerts with totalAlerts=15", () => {
    alertStore.info.totalAlerts = 15;
    const tree = RenderNavbar();
    const brand = tree.find(".navbar-brand");
    expect(brand.text()).toBe("15<FetchIndicator />");
  });

  it("navbar-nav includes 'flex-row' class with 0 filters", () => {
    ValidateNavClass(0, "flex-row");
  });

  it("navbar-nav includes 'flex-row' class with 1 filter", () => {
    ValidateNavClass(1, "flex-row");
  });

  it("navbar-nav includes 'flex-column' class with 2 filters", () => {
    ValidateNavClass(2, "flex-column");
  });

  it("navbar-nav includes 'flex-column' class with 3 filters", () => {
    ValidateNavClass(3, "flex-column");
  });

  it("body 'padding-top' style is updated after calling NavbarOnResize()", () => {
    const tree = MountedNavbar();
    tree.instance().onResize(0, 10);
    expect(
      window
        .getComputedStyle(document.body, null)
        .getPropertyValue("padding-top")
    ).toBe("14px");

    tree.instance().onResize(0, 36);
    expect(
      window
        .getComputedStyle(document.body, null)
        .getPropertyValue("padding-top")
    ).toBe("40px");
  });
});

describe("<IdleTimer />", () => {
  beforeAll(() => {
    jest.useFakeTimers();
  });

  it("hides navbar after 12 seconds on mobile", () => {
    global.window.innerWidth = 500;
    const tree = MountedNavbar();
    jest.runTimersToTime(1000 * 13);
    tree.update();
    expect(tree.find(".container").hasClass("visible")).toBe(false);
    expect(tree.find(".container").hasClass("invisible")).toBe(true);
  });

  it("hides navbar after 3 minutes on desktop", () => {
    global.window.innerWidth = 769;
    const tree = MountedNavbar();
    jest.runTimersToTime(1000 * 60 * 3 + 1000);
    tree.update();
    expect(tree.find(".container").hasClass("visible")).toBe(false);
    expect(tree.find(".container").hasClass("invisible")).toBe(true);
  });

  it("hidden navbar shows up again after activity", () => {
    const tree = MountedNavbar();
    const instance = tree.instance();

    instance.activityStatus.setIdle();
    jest.runOnlyPendingTimers();
    tree.update();
    expect(tree.find(".container").hasClass("visible")).toBe(false);
    expect(tree.find(".container").hasClass("invisible")).toBe(true);

    instance.activityStatus.setActive();
    jest.runOnlyPendingTimers();
    tree.update();
    expect(tree.find(".container").hasClass("visible")).toBe(true);
    expect(tree.find(".container").hasClass("invisible")).toBe(false);
  });

  it("body padding-top is 0px when navbar is hidden", () => {
    const tree = MountedNavbar();
    const instance = tree.instance();

    instance.activityStatus.setIdle();
    jest.runOnlyPendingTimers();
    tree.update();
    expect(
      window
        .getComputedStyle(document.body, null)
        .getPropertyValue("padding-top")
    ).toBe("0px");
  });

  it("doesn't hide when autohide is disabled in settingsStore", () => {
    settingsStore.filterBarConfig.config.autohide = false;
    const tree = MountedNavbar();
    jest.runTimersToTime(1000 * 3600);
    tree.update();
    expect(tree.find(".container").hasClass("visible")).toBe(true);
    expect(tree.find(".container").hasClass("invisible")).toBe(false);
  });
});
