/**
 * empty comment line Denis Makarov
 *
 * @author: Denis Makarov
 * @date: 2019-04-23
 */

import * as React from 'react';
import {Resizer} from '../resizer/Resizer';
import {ActionsPanel} from './actions_panel/ActionsPanel';
import {Button, joinClassNames} from '../../index';

import * as styles from './menuSider.m.scss';
import {safeInvoke} from '../../utils/safeInvoke';
import {SearchTextPanel} from './search_text_panel/SearchTextPanel';
import {FilterPanel} from './filter_panel/FilterPanel';

export interface IMenuSiderProps {
    title: string;
    actions?: React.ReactNode;
    footer?: React.ReactNode;
    'data-qaid'?: string;
    extraButtons?: React.ReactNode;

    onStartChangeWidth?: () => void;
    onStopChangeWidth?: () => void;

    canCollapseFull?: boolean;

    noBodyPadding?: boolean;
    noHeader?: boolean;
}

interface IState {
    collapsed: boolean;
}

const MIN_WIDTH = 200;
const MAX_WIDTH = 800;

export class MenuSider extends React.PureComponent<IMenuSiderProps, IState> {

    static readonly SearchTextPanel = SearchTextPanel;
    static readonly FilterPanel = FilterPanel;

    menuContainer = React.createRef<HTMLDivElement>();

    override state: IState = {
        collapsed: false
    };

    get headerClass () {
        return joinClassNames(
            styles.siderHeader,
            [styles.rotated, this.state.collapsed && this.props.canCollapseFull !== true],
            [styles.hidden, this.state.collapsed && this.props.canCollapseFull === true]
        );
    }

    collapse = () => {
        if (this.menuContainer.current) {
            this.menuContainer.current.style.removeProperty('width');
        }

        this.setState({
            collapsed: true
        });
    };

    expand = () => {
        this.setState({
            collapsed: false
        });
    };

    handleOnCollapseClick = () => {
        if (this.menuContainer.current) {
            this.menuContainer.current.style.removeProperty('width');
        }

        this.setState((prevState) => ({
            collapsed: !prevState.collapsed
        }));
    };

    handleMouseMove = (event: MouseEvent) => {
        event.preventDefault();

        if (this.menuContainer.current && event.clientX >= MIN_WIDTH && event.clientX <= MAX_WIDTH) {
            this.menuContainer.current.style.setProperty('width', `${event.clientX}px`);
        }
    };

    onMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
        event.preventDefault();

        if (this.menuContainer.current) {
            this.menuContainer.current.style.setProperty('transition', 'unset');
        }

        document.addEventListener('mousemove', this.handleMouseMove);
        document.addEventListener('mouseup', this.onMouseUp);

        safeInvoke(this.props.onStartChangeWidth);
    };

    onMouseUp = () => {
        if (this.menuContainer.current) {
            this.menuContainer.current.style.setProperty('transition', 'width 200ms');
        }

        document.removeEventListener('mousemove', this.handleMouseMove);
        document.removeEventListener('mouseup', this.onMouseUp);

        safeInvoke(this.props.onStopChangeWidth);
    };

    override render () {
        const {title, actions, canCollapseFull, noBodyPadding, noHeader} = this.props;
        const {collapsed} = this.state;

        const classNames = joinClassNames(
            styles.siderContainer,
            [styles.isCollapsed, collapsed === true],
            [styles.isFullCollapsed, collapsed === true && canCollapseFull === true]
        );

        const sliderListContainerClasses = joinClassNames(
            styles.siderListContainer,
            [styles.noBodyPadding, Boolean(noBodyPadding)]
        );

        return (
            <div
                className={classNames}
                data-qaid={this.props['data-qaid']}
                ref={this.menuContainer}
            >
                {noHeader !== true && (
                    <div className={this.headerClass}>
                        <Button
                            isMinimal={true}
                            isRound={true}
                            onClick={this.handleOnCollapseClick}
                            leftIcon={collapsed ? 'chevron-right-circle' : 'chevron-left-circle'}
                        />
                        {!collapsed && (
                            <div className={styles.headerTextContainer}>
                                <span className={styles.headerText}>
                                    {title}
                                </span>
                                {this.props.extraButtons}
                            </div>
                        )}
                        {collapsed && (
                            <span className={[styles.headerText, styles.rotated].join(' ')}>
                                {title}
                            </span>
                        )}
                    </div>
                )}

                {!collapsed && (
                    <>
                        <div className={sliderListContainerClasses}>
                            {this.props.children}
                        </div>
                        {actions && <ActionsPanel actions={actions} />}
                        {this.props.footer}

                        <div className={styles.resizeContainer}>
                            <Resizer containerRef={this.menuContainer} minWidth={MIN_WIDTH} maxWidth={MAX_WIDTH}/>
                        </div>
                    </>
                )}
            </div>
        );
    }
}
