// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT

import React from 'react';
import { connect } from 'react-redux';

import { CombinedState, ObjectType } from 'reducers/interfaces';
import { createAnnotationsAsync, rememberObject } from 'actions/annotation-actions';
import SetupTagPopoverComponent from 'components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover';

import { Canvas } from 'cvat-canvas-wrapper';
import getCore from 'cvat-core-wrapper';

const cvat = getCore();
interface DispatchToProps {
    onAnnotationCreate(sessionInstance: any, frame: number, states: any[]): void;
    onRememberObject(labelID: number): void;
}

interface StateToProps {
    normalizedKeyMap: Record<string, string>;
    canvasInstance: Canvas;
    jobInstance: any;
    states: any[];
    labels: any[];
    frame: number;
}

function mapDispatchToProps(dispatch: any): DispatchToProps {
    return {
        onAnnotationCreate(sessionInstance: any, frame: number, states: any[]): void {
            dispatch(createAnnotationsAsync(sessionInstance, frame, states));
        },
        onRememberObject(labelID: number): void {
            dispatch(rememberObject({
                activeObjectType: ObjectType.TAG,
                activeLabelID: labelID,
                activeShapeType: undefined,
            }));
        },
    };
}

function mapStateToProps(state: CombinedState): StateToProps {
    const {
        annotation: {
            canvas: { instance: canvasInstance },
            annotations: { states },
            job: { instance: jobInstance, labels },
            player: {
                frame: { number: frame },
            },
        },
        shortcuts: { normalizedKeyMap },
    } = state;

    return {
        canvasInstance: canvasInstance as Canvas,
        jobInstance,
        states,
        labels,
        frame,
        normalizedKeyMap,
    };
}

type Props = StateToProps & DispatchToProps;

interface State {
    selectedLabelID: number;
    frameTags: any[]
    canAddSelectedTag: boolean;
}

class DrawShapePopoverContainer extends React.PureComponent<Props, State> {
    constructor(props: Props) {
        super(props);

        const { states } = props;
        const frameTags = states.filter((objectState: any): boolean => objectState.objectType === ObjectType.TAG);

        const defaultLabelID = props.labels[0].id;
        this.state = {
            selectedLabelID: defaultLabelID,
            canAddSelectedTag: frameTags.every((objectState: any): boolean => objectState.label.id !== defaultLabelID),
            frameTags,
        };
    }

    public componentDidUpdate(prevProps: Props, prevState: State): void {
        const { frameTags: prevFrameTags } = prevState;
        const { frame: prevFrame } = prevProps;
        const { states, frame } = this.props;
        const frameTags = states.filter((objectState: any): boolean => objectState.objectType === ObjectType.TAG);
        if (prevFrame === frame && prevFrameTags.length === frameTags.length) return;

        const { selectedLabelID } = this.state;
        const canAddSelectedTag =
                        frameTags.every((objectState: any): boolean => objectState.label.id !== selectedLabelID);

        this.setState({
            frameTags,
            canAddSelectedTag,
        });
    }

    private onChangeLabel = (value: any): void => {
        const { onRememberObject } = this.props;
        const { frameTags } = this.state;
        const canAddSelectedTag = frameTags.every((objectState: any): boolean => objectState.label.id !== value.id);
        onRememberObject(value.id);

        this.setState({
            selectedLabelID: value.id,
            canAddSelectedTag,
        });
    };

    private onSetup = (): void => {
        const {
            frame, labels, jobInstance, canvasInstance, onAnnotationCreate, onRememberObject,
        } = this.props;

        const { selectedLabelID, canAddSelectedTag } = this.state;
        if (canAddSelectedTag) {
            canvasInstance.cancel();

            onRememberObject(selectedLabelID);

            const objectState = new cvat.classes.ObjectState({
                objectType: ObjectType.TAG,
                label: labels.filter((label: any) => label.id === selectedLabelID)[0],
                frame,
            });

            onAnnotationCreate(jobInstance, frame, [objectState]);
        }
    };

    public render(): JSX.Element {
        const { selectedLabelID } = this.state;
        const { normalizedKeyMap, labels } = this.props;

        return (
            <SetupTagPopoverComponent
                labels={labels}
                selectedLabelID={selectedLabelID}
                repeatShapeShortcut={normalizedKeyMap.SWITCH_DRAW_MODE}
                onChangeLabel={this.onChangeLabel}
                onSetup={this.onSetup}
            />
        );
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(DrawShapePopoverContainer);
