import * as React from 'react';
import {
  SelectAllControlKeys,
  SelectControlKey,
  SelectDisplayType,
} from '../../able';
import { Layer } from '../layer';
import { TransformData, Entity } from '../../../common';
import { PlaygroundConfigEntity } from '../config';
import clx from 'clsx';
import { SelectorBounds, SelectorBoundsProps } from './selector-bounds';

export interface SelectorEntityRendererProps {
  playgroundConfig: PlaygroundConfigEntity;
  dispatch: Layer['dispatch']; // 事件分发器
  hovered: boolean; // 是否出在hover状态
  selected: boolean; // 是否为选中状态
  multipleSelected: boolean; // 多个节点被选中
  isMoving: boolean; // 是否在移动中
  isInOperation: boolean; // 操作中
  focused: boolean;
  boundsProps: SelectorBoundsProps;
  scale: number; // 缩放
  displayType: SelectDisplayType; // 展示类型
  selectableEntities: Entity[]; // 所有可被选中的实体
  selectControlKeys: SelectControlKey[];
  originBtnDisabled?: boolean; // 中心点是否可点
  children?: React.JSX.Element[] | React.JSX.Element;
  style?: React.CSSProperties;
  className?: string;
  entity: Entity; // 当前实体
  deco?: any;
  extendRenderer?: (props: SelectorEntityRendererProps) => React.JSX.Element; // 扩展
  onControlClick: (key: string, e: React.MouseEvent) => void; // 点击节点控制器触发逻辑, TODO 需要再优化, 并支持吸附能力
  onDoubleClick?: (event: React.MouseEvent) => void;
  // onExtendClick?: (v: SelectorExtendType | 'updateData', node: any, value?: any) => void;
  elemState?: 'all' | 'point' | 'line'; // all: 全部显示, point: 显示点和线，隐藏 extendRenderer, line: 只显示线
}

/**
 * 实体渲染器
 */
export type SelectorEntityRenderer = (
  props: SelectorEntityRendererProps
) => React.JSX.Element;

export function DefaultSelectorEntityRenderer(
  props: SelectorEntityRendererProps
): React.JSX.Element {
  const { elemState = 'all' } = props;
  // 没有子节点或没有样式情况下且没有选中，则不做任何渲染，提升性能
  const needRenderer = props.style || props.className || props.children;
  if (!props.selected && !props.hovered && !needRenderer) return <></>;
  if (props.selected && props.multipleSelected && !needRenderer) return <></>;
  const hideExtendRenderer = elemState !== 'all';
  const hidePoint = elemState === 'line';
  const selected = props.selected && !props.multipleSelected;
  const className = clx(
    'gedit-selector-node',
    {
      hovered: props.hovered,
      selected: selected,
      focused: props.focused,
      [props.boundsProps.className ? props.boundsProps.className : '']: true,
    },
    props.className
  );
  const transform = props.entity.getData<TransformData>(TransformData)!;
  const { origin, worldDegree: rotate } = transform;
  // 先择器不带旋转，旋转样式里按制；
  const bounds = transform.boundsWithoutRotation;
  const boundsWorld = transform.bounds;
  const style: React.CSSProperties = {
    ...props.boundsProps.style,
    ...props.style,
    transformOrigin: `${origin.x * 100}% ${origin.y * 100}%`,
  };
  const onControlMouseDown = (key: string) => (e: React.MouseEvent) => {
    props.onControlClick(key, e);
  };
  let childNodes: React.JSX.Element[] =
    !selected || props.isMoving || hidePoint
      ? []
      : SelectAllControlKeys.filter(k =>
        props.selectControlKeys.includes(k)
      ).map(key => {
        const style: React.CSSProperties =
            key === 'origin'
              ? {
                left: origin.x * 100 + '%',
                top: origin.y * 100 + '%',
                zIndex: 61,
                pointerEvents: props.originBtnDisabled ? 'none' : undefined,
              }
              : {};
        return (
          <div
            key={key}
            className={`gedit-selector-control ${key}`}
            style={style}
            onMouseDown={onControlMouseDown(key)}
          />
        );
      });
  if (props.children) {
    childNodes = childNodes.concat(props.children);
  }
  // const ang = transform.rotation / Math.PI * 180;
  // const leftRotate90 = ang > 30 && ang < 150 ? 30 : 0; // 30 为避免与旋转按钮重叠
  return (
    <>
      <SelectorBounds
        {...props.boundsProps}
        rotate={rotate}
        bounds={bounds}
        focused={props.focused}
        scale={props.scale}
        displayType={props.displayType}
        className={className}
        style={style}
        onDoubleClick={props.onDoubleClick}
      >
        {childNodes}
      </SelectorBounds>
      {/* <SelectorBounds  bounds={boundsWorld} scale={props.scale} displayType={props.displayType} className={className}
        style={style}/> */}
      {!hideExtendRenderer &&
        props.extendRenderer &&
        !props.isInOperation &&
        selected && (
        <div
          style={{
            left: (boundsWorld.x + boundsWorld.width) * props.scale + 30 || 0, // 30 为避免与旋转按钮重叠
            top: (boundsWorld.y + boundsWorld.height / 2) * props.scale || 0,
            zIndex: 100,
            position: 'absolute',
          }}
        >
          {props.extendRenderer(props)}
        </div>
      )}
    </>
  );
}
