import { proxy, useProps } from "@odoo/owl";
import { ActionSpec } from "../../../actions/action";
import { FIRST_TABLE_IN_SELECTION } from "../../../actions/menu_items_actions";
import { DEFAULT_TABLE_CONFIG } from "../../../helpers/table_presets";
import { interactiveCreateTable } from "../../../helpers/ui/table_interactive";
import { cellPositions } from "../../../helpers/zones";
import { Component } from "../../../owl3_compatibility_layer";
import { _t } from "../../../translation";
import { UID } from "../../../types/misc";
import { PropsOf } from "../../../types/props_of";
import { SpreadsheetChildEnv } from "../../../types/spreadsheet_env";
import { TableConfig } from "../../../types/table";
import { ActionButton } from "../../action_button/action_button";
import { ToolBarDropdownStore, useToolBarDropdownStore } from "../../helpers/top_bar_tool_hook";
import { Popover } from "../../popover/popover";
import { types } from "../../props_validation";
import {
  CustomTablePopoverMouseEvent,
  TableStylesPopover,
} from "../table_styles_popover/table_styles_popover";

interface State {
  popoverProps: PropsOf<Popover> | undefined;
}

export class TableDropdownButton extends Component<SpreadsheetChildEnv> {
  static template = "o-spreadsheet-TableDropdownButton";
  static components = { TableStylesPopover, ActionButton };

  protected props = useProps({
    class: types.string().optional(),
  });

  topBarToolStore!: ToolBarDropdownStore;
  state = proxy<State>({ popoverProps: undefined });

  setup() {
    this.topBarToolStore = useToolBarDropdownStore();
  }

  onStylePicked(styleId: string) {
    const sheetId = this.env.model.getters.getActiveSheetId();
    const tableConfig = { ...this.tableConfig, styleId };
    const result = interactiveCreateTable(this.env, sheetId, tableConfig);
    if (result.isSuccessful) {
      const table = FIRST_TABLE_IN_SELECTION(this.env);
      if (table) {
        this.env.openSidePanel("TableSidePanel", { table });
      }
    }
    this.closePopover();
  }

  onClick(ev: CustomTablePopoverMouseEvent) {
    if (ev.hasClosedTableStylesPopover || this.state.popoverProps) {
      this.closePopover();
      return;
    }
    const pivotId = this.dynamicPivotIdInSelection;
    if (pivotId) {
      this.env.openSidePanel("PivotSidePanel", { pivotId, openTab: "design" });
      return;
    }
    const table = FIRST_TABLE_IN_SELECTION(this.env);
    if (table) {
      this.topBarToolStore.closeDropdowns();
      this.env.toggleSidePanel("TableSidePanel", { table });
      return;
    }

    const target = ev.currentTarget as HTMLElement;
    const { left, bottom } = target.getBoundingClientRect();
    this.topBarToolStore.openDropdown();
    this.state.popoverProps = {
      anchorRect: { x: left, y: bottom, width: 0, height: 0 },
      positioning: "bottom-left",
      verticalOffset: 0,
    };
  }

  private closePopover() {
    this.state.popoverProps = undefined;
  }

  get action(): ActionSpec {
    const pivotId = this.dynamicPivotIdInSelection;
    if (pivotId) {
      return {
        name: _t("Edit pivot style"),
        icon: "o-spreadsheet-Icon.EDIT_TABLE",
      };
    }

    return {
      name: (env) => (FIRST_TABLE_IN_SELECTION(env) ? _t("Edit table") : _t("Insert table")),
      icon: (env) =>
        FIRST_TABLE_IN_SELECTION(env)
          ? "o-spreadsheet-Icon.EDIT_TABLE"
          : "o-spreadsheet-Icon.PAINT_TABLE",
    };
  }

  get tableConfig(): TableConfig {
    return { ...DEFAULT_TABLE_CONFIG, numberOfHeaders: 1, bandedRows: true };
  }

  get tableStyles() {
    return this.env.model.getters.getTableStyles();
  }

  get dynamicPivotIdInSelection(): UID | undefined {
    const selection = this.env.model.getters.getSelectedZones();
    const pivotCellIds = new Set(this.env.model.getters.getCellsWithTrackedFormula("PIVOT"));
    if (pivotCellIds.size === 0) {
      return undefined;
    }

    const activeSheetId = this.env.model.getters.getActiveSheetId();
    for (const zone of selection) {
      for (const position of cellPositions(activeSheetId, zone)) {
        const mainPosition = this.env.model.getters.getArrayFormulaSpreadingOn(position);
        if (!mainPosition) {
          continue;
        }
        const cellId = this.env.model.getters.getCell(mainPosition)?.id;
        if (cellId && pivotCellIds.has(cellId)) {
          const pivotId = this.env.model.getters.getPivotIdFromPosition(mainPosition);
          if (pivotId) {
            return pivotId;
          }
        }
      }
    }

    return undefined;
  }

  get class() {
    return `${this.props.class ? this.props.class : ""} ${
      this.env.model.getters.isCurrentSheetLocked() ? "o-disabled" : ""
    }`;
  }
}
