import { providePlugins, xml } from "@odoo/owl";
import { Model, UID } from "../../src";
import { PopoverContainerPlugin } from "../../src/components/popover/popover_container_owl_plugin";
import { SidePanels } from "../../src/components/side_panel/side_panels/side_panels";
import { TableDropdownButton } from "../../src/components/tables/table_dropdown_button/table_dropdown_button";
import { toZone, zoneToXc } from "../../src/helpers/zones";
import { Component } from "../../src/owl3_compatibility_layer";
import { SpreadsheetChildEnv } from "../../src/types/spreadsheet_env";
import { createTable, setSelection } from "../test_helpers/commands_helpers";
import { click } from "../test_helpers/dom_helper";
import { mountComponent, nextTick, setGrid } from "../test_helpers/helpers";
import { addPivot } from "../test_helpers/pivot_helpers";

let model: Model;
let sheetId: UID;
let fixture: HTMLElement;

class Parent extends Component<SpreadsheetChildEnv> {
  static components = { TableDropdownButton, SidePanels };
  static template = xml/*xml*/ `
  <div class="o-spreadsheet">
    <TableDropdownButton />
    <SidePanels />
  </div>
  `;

  setup() {
    providePlugins([PopoverContainerPlugin], {
      getPopoverContainerRect: () => ({ x: 0, y: 0, height: 1000, width: 1000 }),
    });
  }
}

beforeEach(async () => {
  ({ model, fixture } = await mountComponent(Parent, {}));
  sheetId = model.getters.getActiveSheetId();
});

describe("Table dropdown button", () => {
  test("Can insert a table with the widget", async () => {
    setSelection(model, ["A1:C3"]);
    await click(fixture, ".o-table-widget .o-menu-item-button");
    await click(fixture, '.o-table-style-popover div[title="Red, TableStyleMedium3"]');

    expect(model.getters.getTables(sheetId)).toMatchObject([
      { range: { zone: toZone("A1:C3") }, config: { styleId: "TableStyleMedium3" } },
    ]);
    expect(fixture.querySelector(".o-table-panel")).toBeTruthy();
  });

  test("Re-clicking on the widget toggles the popover", async () => {
    await click(fixture, ".o-table-widget .o-menu-item-button");
    expect(fixture.querySelector(".o-table-style-popover")).toBeTruthy();

    await click(fixture, ".o-table-widget .o-menu-item-button");
    expect(fixture.querySelector(".o-table-style-popover")).toBeFalsy();
  });

  test("No table is selected inside the popover", async () => {
    await click(fixture, ".o-table-widget .o-menu-item-button");
    expect(fixture.querySelector(".o-table-style-list-item.selected")).toBeNull();
  });

  test("Clicking on the widget toggle the side panel if the selection contains a table", async () => {
    setSelection(model, ["A1:C3"]);
    createTable(model, "A1:C3");
    await click(fixture, ".o-table-widget .o-menu-item-button");
    await nextTick();
    expect(fixture.querySelector(".o-table-panel")).toBeTruthy();
    await click(fixture, ".o-table-widget .o-menu-item-button");
    expect(fixture.querySelector(".o-table-panel")).toBeFalsy();
  });

  test("Can insert a table with a custom style with the widget", async () => {
    setSelection(model, ["A1:C3"]);
    await click(fixture, ".o-table-widget .o-menu-item-button");
    await click(fixture, ".o-notebook-tab[data-id='custom']");
    await click(fixture, ".o-new-table-style");

    expect(fixture.querySelector(".o-table-style-editor-panel")).toBeTruthy();
    await click(fixture, ".o-sidePanel .o-confirm");
    const table = model.getters.getTables(sheetId)[0];
    expect(zoneToXc(table.range.zone)).toEqual("A1:C3");
    expect(model.getters.getTableStyle(table.config.styleId).displayName).toEqual(
      "Custom Table Style"
    );
  });

  test("Clicking on the widget open the pivot side panel if there is a dynamic pivot in the selection", async () => {
    setGrid(model, { A1: "Price", A2: "10", A3: "=PIVOT(1)" });
    addPivot(model, "A1:A2", {});
    setSelection(model, ["A3"]);
    await nextTick();

    expect(".o-table-widget .o-menu-item-button").toHaveAttribute("title", "Edit pivot style");

    setSelection(model, ["A5"]); // Spread result
    await nextTick();
    expect(".o-table-widget .o-menu-item-button").toHaveAttribute("title", "Edit pivot style");

    await click(fixture, ".o-table-widget .o-menu-item-button");
    expect(".o-pivot-panel").toHaveCount(1);
    expect(".o-sidePanel-tab.o-panel-design").not.toHaveClass("inactive");
  });

  test("Clicking on the widget create a new table if there is a static pivot in the selection", async () => {
    setGrid(model, { A1: "Price", A2: "10", A3: "=PIVOT.HEADER(1)" });
    addPivot(model, "A1:A2", {});
    setSelection(model, ["A3"]);
    await nextTick();

    expect(".o-table-widget .o-menu-item-button").toHaveAttribute("title", "Insert table");
    await click(fixture, ".o-table-widget .o-menu-item-button");
    expect(".o-table-style-popover").toHaveCount(1);
  });
});
