import { useProps } from "@odoo/owl";
import { AUTOFILL_EDGE_LENGTH } from "../../../constants";
import { useStore } from "../../../store_engine/store_hooks";
import { ViewportsStore } from "../../../stores/viewports_store";
import { ResizeDirection } from "../../../types/figure";
import { SpreadsheetChildEnv } from "../../../types/spreadsheet_env";
import { cssPropertiesToCss } from "../../helpers/css";
import { types } from "../../props_validation";

import { Component } from "../../../owl3_compatibility_layer";
import { Store } from "../../../types/store_engine";
const MOBILE_HANDLER_WIDTH = 40;

type Orientation = "nw" | "ne" | "sw" | "se" | "n" | "s" | "e" | "w";

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

  protected props = useProps({
    zone: types.Zone(),
    color: types.Color(),
    orientation: types.or([
      types.literal("nw"),
      types.literal("ne"),
      types.literal("sw"),
      types.literal("se"),
      types.literal("n"),
      types.literal("s"),
      types.literal("e"),
      types.literal("w"),
    ]),
    isResizing: types.boolean(),
    onResizeHighlight:
      types.function<(ev: PointerEvent, dirX: ResizeDirection, dirY: ResizeDirection) => void>(),
  });
  private dirX!: ResizeDirection;
  private dirY!: ResizeDirection;
  private viewStore!: Store<ViewportsStore>;

  setup(): void {
    this.viewStore = useStore(ViewportsStore);
    const { dirX, dirY } = orientationToDir(this.props.orientation);
    this.dirX = dirX;
    this.dirY = dirY;
  }

  get handlerStyle() {
    const z = this.props.zone;

    const rect = this.viewStore.viewports.getVisibleRect(
      this.env.model.getters.getActiveSheetId(),
      {
        left: this.dirX === 1 ? z.right : z.left,
        right: this.dirX === -1 ? z.left : z.right,
        top: this.dirY === 1 ? z.bottom : z.top,
        bottom: this.dirY === -1 ? z.top : z.bottom,
      }
    );

    // Don't show if not visible in the viewport
    if (rect.width * rect.height === 0) {
      return `display: none !important;`;
    }

    const leftValue = rect.x + rect.width / 2 + (this.dirX * rect.width) / 2;
    const topValue = rect.y + rect.height / 2 + (this.dirY * rect.height) / 2;

    const edgeLength = this.getHandlerEdgeLength();
    const css = {
      left: `${leftValue - edgeLength / 2}px`,
      top: `${topValue - edgeLength / 2}px`,
      height: `${edgeLength}px`,
      width: `${edgeLength}px`,
    };
    if (this.env.isMobile()) {
      css["border-radius"] = `${edgeLength / 2}px`;
    }

    return cssPropertiesToCss(css);
  }

  getHandlerEdgeLength() {
    return this.env.isMobile() ? MOBILE_HANDLER_WIDTH : AUTOFILL_EDGE_LENGTH;
  }

  get buttonLook() {
    const css = {
      "background-color": this.props.color,
      cursor: `${this.props.orientation}-resize`,
    };
    if (this.env.isMobile()) {
      css["border-radius"] = `${AUTOFILL_EDGE_LENGTH / 2}px`;
    }
    return cssPropertiesToCss(css);
  }

  onMouseDown(ev: PointerEvent) {
    this.props.onResizeHighlight(ev, this.dirX, this.dirY);
  }
}

function orientationToDir(or: Orientation): { dirX: ResizeDirection; dirY: ResizeDirection } {
  const dirX = or.includes("w") ? -1 : or.includes("e") ? 1 : 0;
  const dirY = or.includes("n") ? -1 : or.includes("s") ? 1 : 0;

  return { dirX, dirY };
}
