import * as React from "react";
import { MoveableProps, Able, MoveableInterface, RectInfo } from "./types";
import MoveableManager from "./MoveableManager";
import { MOVEABLE_ABLES } from "./ables/consts";
import MoveableGroup from "./MoveableGroup";
import { ref } from "framework-utils";
import { isArray } from "@daybrush/utils";
import Groupable from "./ables/Groupable";

export default class Moveable<T = {}> extends React.PureComponent<MoveableProps & T> implements MoveableInterface {
    public moveable!: MoveableManager<MoveableProps> | MoveableGroup;
    public render() {
        const props = this.props;
        const ables: Able[] = props.ables as Able[] || [];
        const target = this.props.target || this.props.targets;
        const isArr = isArray(target);
        const isGroup = isArr && (target as any[]).length > 1;

        if (isGroup) {
            const nextProps = {
                ...this.props,
                target: null,
                targets: target as any[],
                ables: [...MOVEABLE_ABLES, Groupable, ...ables],
            };
            return <MoveableGroup key="group" ref={ref(this, "moveable")}
                {...nextProps} />;
        } else {
            const moveableTarget = isArr ? (target as any[])[0] : target;

            return <MoveableManager key="single" ref={ref(this, "moveable")}
                {...{ ...this.props, target: moveableTarget, ables: [...MOVEABLE_ABLES, ...ables] }} />;
        }
    }
    public isMoveableElement(target: HTMLElement) {
        return this.moveable.isMoveableElement(target);
    }
    public dragStart(e: MouseEvent | TouchEvent) {
        this.moveable.dragStart(e);
    }
    public isInside(clientX: number, clientY: number) {
        return this.moveable.isInside(clientX, clientY);
    }
    public updateRect() {
        this.moveable.updateRect();
    }
    public updateTarget() {
        this.moveable.updateTarget();
    }
    public getRect(): RectInfo {
        return this.moveable.getRect();
    }
    public destroy() {
        this.moveable.componentWillUnmount();
    }
}
