import { proxy, useProps } from "@odoo/owl";
import { Component } from "../../../owl3_compatibility_layer";
import { useStore } from "../../../store_engine/store_hooks";
import { TableResizeStore } from "../../../stores/table_resize_store";
import { ViewportsStore } from "../../../stores/viewports_store";
import { ZoomStore } from "../../../stores/zoom_store";
import { HeaderIndex, Highlight, Zone } from "../../../types/misc";
import { SpreadsheetChildEnv } from "../../../types/spreadsheet_env";
import { Store } from "../../../types/store_engine";
import { cssPropertiesToCss } from "../../helpers/css";
import { useDragAndDropBeyondTheViewport } from "../../helpers/drag_and_drop_grid_hook";
import { useHighlights } from "../../helpers/highlight_hook";
import { types } from "../../props_validation";

const SIZE = 3;
const COLOR = "#777";

interface State {
  highlightZone: Zone | undefined;
}

export class TableResizer extends Component<SpreadsheetChildEnv> {
  static template = "o-spreadsheet-TableResizer";

  protected props = useProps({
    table: types.Table(),
  });

  state = proxy<State>({ highlightZone: undefined });
  dragNDropGrid = useDragAndDropBeyondTheViewport(this.env);
  private viewStore!: Store<ViewportsStore>;
  private zoomStore!: Store<ZoomStore>;

  setup(): void {
    useHighlights(this);
    this.viewStore = useStore(ViewportsStore);
    useStore(TableResizeStore);
    this.zoomStore = useStore(ZoomStore);
  }

  get containerStyle(): string {
    const sheetId = this.props.table.range.sheetId;
    const tableZone = this.props.table.range.zone;
    const bottomRight = { ...tableZone, left: tableZone.right, top: tableZone.bottom };
    const rect = this.viewStore.viewports.getVisibleRect(sheetId, bottomRight);
    if (rect.height === 0 || rect.width === 0) {
      return cssPropertiesToCss({ display: "none" });
    }

    return cssPropertiesToCss({
      top: `${rect.y + rect.height - SIZE * 2}px`,
      left: `${rect.x + rect.width - SIZE * 2}px`,
    });
  }

  onMouseDown(ev: PointerEvent) {
    const tableZone = this.props.table.range.zone;
    const topLeft = { col: tableZone.left, row: tableZone.top };
    document.body.style.cursor = "nwse-resize";
    const zoomedMouseEvent = this.zoomStore.getZoomedEvent(ev);

    const onMouseUp = () => {
      document.body.style.cursor = "";
      const newTableZone = this.state.highlightZone;
      if (!newTableZone) {
        return;
      }
      const sheetId = this.props.table.range.sheetId;
      this.env.model.dispatch("RESIZE_TABLE", {
        sheetId,
        zone: this.props.table.range.zone,
        newTableRange: this.env.model.getters.getRangeDataFromZone(sheetId, newTableZone),
      });
      this.state.highlightZone = undefined;
    };

    const onMouseMove = (col: HeaderIndex, row: HeaderIndex, ev: MouseEvent) => {
      this.state.highlightZone = {
        left: topLeft.col,
        top: topLeft.row,
        right: Math.max(col, topLeft.col),
        bottom: Math.max(row, topLeft.row),
      };
    };
    this.dragNDropGrid.start(zoomedMouseEvent, onMouseMove, onMouseUp);
  }

  get highlights(): Highlight[] {
    if (!this.state.highlightZone) {
      return [];
    }
    return [
      {
        range: this.env.model.getters.getRangeFromZone(
          this.props.table.range.sheetId,
          this.state.highlightZone
        ),
        color: COLOR,
        noFill: true,
      },
    ];
  }
}
