import SeismicControl from '../../helix/javascript/array_summary/seismic_control';
import $ from 'jquery';
import 'jasmine-jquery';

describe('Seismic Control', function () {
  let htmlContent = '<div id="add_seismic" class="seismic_control"></div>' +
    '<div id="remove_seismic" class="seismic_control"></div>' +
    '<div id="save_seismic_changes" class="seismic_control"></div>' +
    '<div id="seismic_save" class="hidden">' +
      '<div class="seismic_save_message"></div>' +
      '<div class="dismiss_button"></div>' +
      '<div class="circle"></div>' +
    '</div>';
  let visualizationSpy;
  let subarrayDisplaySpy;
  let subject;

  beforeEach(function () {
    setFixtures(htmlContent);
    visualizationSpy = jasmine.createSpyObj('arrayVisualization', ['addSeismicAnchor', 'removeSeismicAnchor', 'refreshPanels']);
    subarrayDisplaySpy = jasmine.createSpyObj('subarrayDisplay', ['didUpdateSubarrayData']);
    subject = new SeismicControl(visualizationSpy, subarrayDisplaySpy);
    subject.init($('*'), $("#seismic_save"));
  });

  describe("clicking the add seismic anchor button", function () {
    beforeEach(function () {
      $("#add_seismic").click();
    });

    it("tells the visualization to add a seismic anchor", function () {
      expect(visualizationSpy.addSeismicAnchor).toHaveBeenCalled();
    });
  });

  describe("clicking the remove seismic anchor button", function () {
    beforeEach(function () {
      $("#remove_seismic").click();
    });

    it("clicking the add seismic anchor button tells the visualization to remove a seismic anchor", function () {
      expect(visualizationSpy.removeSeismicAnchor).toHaveBeenCalled();
    });
  });

  describe("clicking the save button", function () {
    let panelData = [{data: {panel_id: "foo", seismic_anchors: 0}}];
    let deferred;
    let receivedRequest;

    beforeEach(function () {
      visualizationSpy.panelData = panelData;
      deferred = $.Deferred();
      spyOn($, 'ajax').and.callFake(function (request) {
        receivedRequest = request;
        return deferred.promise();
      });

      $("#save_seismic_changes").click();
    });

    it("sends an ajax request saving the panel data", function () {
      expect(receivedRequest).not.toBeUndefined();
      expect(receivedRequest.url).toEqual("/api/update_panel_data");
      expect(receivedRequest.data).toEqual(JSON.stringify([{panel_id: "foo", seismic_anchors: 0}]));
      expect(receivedRequest.method).toEqual("POST");
    });

    describe("when the request succeeds", function () {
      let panelData = {foo: "bar"};
      let subarrayData = {baz: 'qux'};
      beforeEach(function () {
        deferred.resolve({status: "success", error: null, panel_data: panelData, subarray_data: subarrayData});
      });

      it("informs the user of the success", function () {
        expect($("#seismic_save")).not.toHaveClass("hidden");
        expect($("#seismic_save")).toHaveClass("seismic_success");
        expect($(".seismic_save_message")).toHaveText("Changes to the Seismic Anchors have been successfully saved!");
      });

      it("shows the ok icon in the banner", function () {
        expect($(".circle")).toHaveClass("icon-ok");
        expect($(".circle")).not.toHaveText("!");
      });

      it("hides the banner again when the user clicks the dismiss button", function () {
        $(".dismiss_button").click();

        expect($("#seismic_save")).toHaveClass("hidden");
        expect($("#seismic_save")).not.toHaveClass("seismic_success");
      });

      it("tells the array visualization to reflash", function () {
        expect(visualizationSpy.refreshPanels).toHaveBeenCalledWith(panelData);
      });

      it("informs the subarrayDisplay that we have new subarrayData", function () {
        expect(subarrayDisplaySpy.didUpdateSubarrayData).toHaveBeenCalledWith(subarrayData);
      });
    });

    describe("when the request fails validation", function () {
      let subarrayData = {baz: 'qux'};
      beforeEach(function () {
        deferred.resolve({status: "error", error: "The validation failed", panel_data: null, subarray_data: subarrayData});
      });

      it("shows the error", function () {
        expect($("#seismic_save")).not.toHaveClass("hidden");
        expect($("#seismic_save")).toHaveClass("seismic_error");
        expect($(".seismic_save_message")).toHaveText("The validation failed");
      });

      it("shows the error icon in the banner", function () {
        expect($(".circle")).not.toHaveClass("icon-ok");
        expect($(".circle")).toHaveText("!");
      });

      it("hides the banner again when the user clicks the dismiss button", function () {
        $(".dismiss_button").click();

        expect($("#seismic_save")).toHaveClass("hidden");
        expect($("#seismic_save")).not.toHaveClass("seismic_error");
      });

      it("does not tell the array visualization to reflash", function () {
        expect(visualizationSpy.refreshPanels).not.toHaveBeenCalled();
      });

      it("informs the subarrayDisplay that we have new subarrayData", function () {
        expect(subarrayDisplaySpy.didUpdateSubarrayData).toHaveBeenCalledWith(subarrayData);
      });
    });

    describe("when the request fails otherwise", function () {
      beforeEach(function () {
        deferred.resolve({});
      });

      it("shows the error", function () {
        expect($("#seismic_save")).not.toHaveClass("hidden");
        expect($("#seismic_save")).toHaveClass("seismic_error");
        expect($(".seismic_save_message")).toHaveText("Unknown error, please try again.");
      });

      it("shows the error icon in the banner", function () {
        expect($(".circle")).not.toHaveClass("icon-ok");
        expect($(".circle")).toHaveText("!");
      });

      it("hides the banner again when the user clicks the dismiss button", function () {
        $(".dismiss_button").click();

        expect($("#seismic_save")).toHaveClass("hidden");
        expect($("#seismic_save")).not.toHaveClass("seismic_error");
      });

      it("does not tell the array visualization to reflash", function () {
        expect(visualizationSpy.refreshPanels).not.toHaveBeenCalled();
      });

      it("informs the subarrayDisplay that we have new subarrayData", function () {
        expect(subarrayDisplaySpy.didUpdateSubarrayData).not.toHaveBeenCalled();
      });
    });
  });
});