import { css } from '@emotion/css';
import React from 'react';

import { GrafanaTheme2 } from '@grafana/data/src';
import { IconButton, useStyles2 } from '@grafana/ui/src';
import { HorizontalConstraint, Placement, QuickPlacement, VerticalConstraint } from 'app/features/canvas';
import { ElementState } from 'app/features/canvas/runtime/element';

import { CanvasEditorOptions } from './elementEditor';

type Props = {
  onPositionChange: (value: number | undefined, placement: keyof Placement) => void;
  element: ElementState;
  settings: CanvasEditorOptions;
};

export const QuickPositioning = ({ onPositionChange, element, settings }: Props) => {
  const styles = useStyles2(getStyles);

  const onQuickPositioningChange = (position: QuickPlacement) => {
    const defaultConstraint = { vertical: VerticalConstraint.Top, horizontal: HorizontalConstraint.Left };
    const originalConstraint = { ...element.options.constraint };

    element.options.constraint = defaultConstraint;
    element.setPlacementFromConstraint();

    switch (position) {
      case QuickPlacement.Top:
        onPositionChange(0, 'top');
        break;
      case QuickPlacement.Bottom:
        onPositionChange(getRightBottomPosition(element.options.placement?.height ?? 0, 'bottom'), 'top');
        break;
      case QuickPlacement.VerticalCenter:
        onPositionChange(getCenterPosition(element.options.placement?.height ?? 0, 'v'), 'top');
        break;
      case QuickPlacement.Left:
        onPositionChange(0, 'left');
        break;
      case QuickPlacement.Right:
        onPositionChange(getRightBottomPosition(element.options.placement?.width ?? 0, 'right'), 'left');
        break;
      case QuickPlacement.HorizontalCenter:
        onPositionChange(getCenterPosition(element.options.placement?.width ?? 0, 'h'), 'left');
        break;
    }

    element.options.constraint = originalConstraint;
    element.setPlacementFromConstraint();
  };

  // Basing this on scene will mean that center is based on root for the time being
  const getCenterPosition = (elementSize: number, align: 'h' | 'v') => {
    const sceneSize = align === 'h' ? settings.scene.width : settings.scene.height;

    return (sceneSize - elementSize) / 2;
  };

  const getRightBottomPosition = (elementSize: number, align: 'right' | 'bottom') => {
    const sceneSize = align === 'right' ? settings.scene.width : settings.scene.height;

    return sceneSize - elementSize;
  };

  return (
    <div className={styles.buttonGroup}>
      <IconButton
        name="horizontal-align-left"
        onClick={() => onQuickPositioningChange(QuickPlacement.Left)}
        className={styles.button}
        size="lg"
        tooltip="Align left"
      />
      <IconButton
        name="horizontal-align-center"
        onClick={() => onQuickPositioningChange(QuickPlacement.HorizontalCenter)}
        className={styles.button}
        size="lg"
        tooltip="Align horizontal centers"
      />
      <IconButton
        name="horizontal-align-right"
        onClick={() => onQuickPositioningChange(QuickPlacement.Right)}
        className={styles.button}
        size="lg"
        tooltip="Align right"
      />
      <IconButton
        name="vertical-align-top"
        onClick={() => onQuickPositioningChange(QuickPlacement.Top)}
        size="lg"
        tooltip="Align top"
      />
      <IconButton
        name="vertical-align-center"
        onClick={() => onQuickPositioningChange(QuickPlacement.VerticalCenter)}
        className={styles.button}
        size="lg"
        tooltip="Align vertical centers"
      />
      <IconButton
        name="vertical-align-bottom"
        onClick={() => onQuickPositioningChange(QuickPlacement.Bottom)}
        className={styles.button}
        size="lg"
        tooltip="Align bottom"
      />
    </div>
  );
};

const getStyles = (theme: GrafanaTheme2) => ({
  buttonGroup: css`
    display: flex;
    flex-wrap: wrap;
    padding: 12px 0 12px 0;
  `,
  button: css`
    margin-left: 5px;
    margin-right: 5px;
  `,
});
