import * as React from 'react';
import {CSSProperties} from 'react';
import {IsBoolean, IsDefined, IsString} from 'class-validator';
import {BasicConfig, BasicContainer, BasicContainerPropsInterface} from '../../render/core/Container/types';
import {Button, Modal, Popconfirm} from '@native-ads/antd';
import componentLoader from '../../render/util/componentLoader';
import {ButtonProps} from '@native-ads/antd/lib/button/button';
import * as _ from 'lodash';
import {ButtonType} from '@native-ads/antd/lib/button';
import './Button.less';
import {createChild} from '../../render/util/createChild';
import {ModalFuncProps} from '@native-ads/antd/lib/modal/Modal';
import {ModalConfig} from '../Modal/Modal';

export class NotificationConfig extends ModalConfig {
    /**
     * 提示框标题
     */
    title?: string;

    /**
     * 宽度
     */
    width?: string | number;

    /**
     * 确认按钮文字
     */
    okText?: string;

    /**
     * 确认按钮类型
     */
    okType?: ButtonType;

    /**
     * 取消按钮文字
     */
    cancelText?: string;

    /**
     * 图标 Icon 类型
     */
    iconType?: string;

    /**
     * 点击蒙层是否允许关闭
     */
    maskClosable?: boolean;

    /**
     * 设置 z-index
     */
    zIndex?: number;

    /**
     * 设置自定义内容
     */
    controls: BasicConfig[];
}
export class ButtonConfig extends BasicConfig {
    /**
     * 按钮的文字
     * @public
     */
    @IsString()
    @IsDefined()
    text: string;

    /**
     * 按钮的类型
     * @public
     */
    @IsString()
    buttonType?: 'primary' | 'default' | 'alt' | 'solid' | 'link' | 'link-primary' | undefined;

    /**
     * 按钮的HTML类型 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type
     * @public
     */
    @IsString()
    htmlType?: 'submit' | 'button' | 'reset';

    /**
     * 设置之后, 会弹出一个确认框, 来确认是否要触发click事件
     */
    confirm?: {
        /**
         * 确认框的描述
         */
        title?: string;

        /**
         * 确认按钮文字
         */
        okText?: string;

        /**
         * 确认按钮类型
         */
        okType?: ButtonType;

        /**
         * 取消按钮文字
         */
        cancelText?: string;
    };

    /**
     * 设置之后, 会弹出一个提示框, 提示相关事件
     */
    notification?: NotificationConfig;

    /**
     * 按钮的图标类型
     * @public
     */
    @IsString()
    icon?: string;

    /**
     * 按钮形态
     * @public
     */
    @IsString()
    shape?: 'circle' | 'circle-outline' | undefined;

    /**
     * 按钮大小
     * @public
     */
    @IsString()
    size?: 'small' | 'large' | undefined;

    /**
     * 加载形态
     * @public
     */
    @IsBoolean()
    loading?: boolean;

    /**
     * 按钮背景透明
     * @public
     */
    @IsBoolean()
    ghost?: boolean;

    /**
     * 是否禁用
     * @public
     */
    @IsBoolean()
    disabled?: boolean;

    /**
     * unknown
     */
    @IsString()
    prefixCls?: string;

    /**
     * CSS class
     */
    @IsString()
    className?: string;

    /**
     * 内联CSS属性
     */
    style?: CSSProperties;

    /**
     * 跳转链接
     */
    href?: string;

}

export class ButtonPropsInterface extends BasicContainerPropsInterface {
    info: ButtonConfig;
}

class AbstractButton extends BasicContainer<ButtonPropsInterface, {}> {
    constructor(props: ButtonPropsInterface) {
        super(props);
    }
    render() {
        let info = this.getPropsInfo(this.props.info);
        let text = info.text;
        let mappedProps = this.mapButtonOptions(info);
        let children;
        let childElement;
        let loading = info.loading;
        // if (this.isUnderContainerEnv()) {
        //     loading = this.getValueFromDataStore('$loading');
        // }

        if (info.href) {
            const jump = (event: React.MouseEvent<HTMLAnchorElement>) => {
                event.stopPropagation();
                event.preventDefault();
                window.location.href = info.href!;
            };
            childElement = <a href={info.href} onClick={jump}>{text}</a>;
        } else {
            childElement = text;
        }
        let buttonProps: ButtonProps = {
            onMouseUp: (event: React.MouseEvent<HTMLButtonElement>) => {
                this.commonEventHandler('onMouseUp', {});
            },
            onMouseDown: (event: React.MouseEvent<HTMLButtonElement>) => {
                this.commonEventHandler('onMouseDown', {});
            },
            loading: loading,
            ...mappedProps
        };
        if (_.isPlainObject(info.confirm)) {
            children = (
                <Popconfirm
                    title={info.confirm!.title}
                    okText={info.confirm!.okText}
                    okType={info.confirm!.okType}
                    cancelText={info.confirm!.cancelText}
                    onConfirm={(event: React.MouseEvent<HTMLDivElement>) => {
                        this.commonEventHandler('onConfirm', {});
                    }}
                    onCancel={(event: React.MouseEvent<HTMLDivElement>) => {
                        this.commonEventHandler('onCancel', {});
                    }}
                >
                    <Button {...buttonProps}>{childElement}</Button>
                </Popconfirm>
            );
        } else if (_.isPlainObject(info.notification)) {
            const modalProps = this.mapModalOptions(info.notification!);
            const content = info.notification!.controls.map((childInfo, key) => {
                return createChild(childInfo, {
                    ...this.props,
                    info: childInfo,
                    key: key
                });
            });
            buttonProps.onClick = () => {
                const ref = Modal.warning({
                    content: (
                        content
                    ),
                    onOk: (event: React.MouseEvent<HTMLDivElement>) => {
                        this.commonEventHandler('onOk', {});
                        ref.destroy();
                    },
                    onCancel: (event: React.MouseEvent<HTMLDivElement>) => {
                        this.commonEventHandler('onCancle', {});
                        ref.destroy();
                    },
                    ...modalProps
                });
            };
            children = (
                <Button {...buttonProps}>
                    {childElement}
                </Button>
            );
        } else {
            if (info.confirm) {
                console.error('Button confirm props should be plain Object');
            }

            buttonProps.onClick = (event: React.MouseEvent<HTMLButtonElement>) => {
                this.commonEventHandler('onClick', {});
            };

            children = React.createElement(Button, buttonProps, childElement);
        }

        return this.renderChildren(info, children);
    }

    private mapButtonOptions(info: ButtonConfig): ButtonProps {
        return {
            type: info.buttonType,
            htmlType: info.htmlType,
            icon: info.icon,
            shape: info.shape,
            size: info.size,
            disabled: info.disabled,
            style: info.style,
            prefixCls: info.prefixCls,
            className: info.className,
            ghost: info.ghost,
        };
    }
    private mapModalOptions(info: NotificationConfig): ModalFuncProps {
        return {
            title: info.title,
            width: info.width,
            okText: info.okText,
            okType: info.okType,
            cancelText: info.cancelText,
            maskClosable: info.maskClosable,
            iconType: info.iconType,
            zIndex: info.zIndex,
        };
    }
}

componentLoader.addComponent('button', AbstractButton, ButtonPropsInterface);

export default AbstractButton;
