import { Vue, Component, Watch } from 'vue-property-decorator';
import { CreateElement } from 'vue/types/umd';
import { on, LogUtil } from '@ibizstudio/runtime';
import './app-top-drawer.less';

/**
 * 模态承载组件
 *
 * @export
 * @class AppTopDrawer
 * @extends {Vue}
 */
@Component({})
export class AppTopDrawer extends Vue {
    /**
     * 已呈现视图列表
     *
     * @protected
     * @type {any[]}
     * @memberof AppTopDrawer
     */
    protected viewList: any[] = [];

    /**
     * 为了视觉效果，当前列表为显示的视图
     *
     * @protected
     * @type {any[]}
     * @memberof AppTopDrawer
     */
    protected showViewList: any[] = [];

    /**
     * 关闭模态数据传递
     *
     * @protected
     * @type {*}
     * @memberof AppTopDrawer
     */
    protected closeModalData: any;

    /**
     * 待关闭视图
     *
     * @protected
     * @type {any[]}
     * @memberof AppTopDrawer
     */
    protected toBeClosedViews: any[] = [];

    /**
     * 是否展示模态
     *
     * @protected
     * @type {boolean}
     * @memberof AppTopDrawer
     */
    protected isShow: boolean = false;

    /**
     * 是否显示蒙层
     *
     * @memberof AppTopDrawer
     */
    isShowDialogContainer: boolean = false;

    /**
     * 监控模态展示状态变更
     *
     * @memberof AppTopDrawer
     */
    @Watch('isShow')
    isShowWatch(newVal: boolean, oldVal: boolean): void {
        if (newVal !== oldVal && newVal === false) {
            this.$store.commit('downZIndex');
            this.zIndex = this.$store.getters.getZIndex()
        } else {
            // 滑动动画时间结束后关闭蒙层
            setTimeout(() => {
                this.isShowDialogContainer = false;
            }, 550);
        }
    }

    /**
     * 视图层级
     *
     * @protected
     * @type {number}
     * @memberof AppTopDrawer
     */
    protected zIndex: number = this.$store.getters.getZIndex();

    /**
     * 当前激活项下标
     *
     * @protected
     * @type {number}
     * @memberof AppTopDrawer
     */
    protected activeIndex: number = 0;

    /**
     * 组件创建完毕
     *
     * @protected
     * @memberof AppTopDrawer
     */
    protected created(): void {
        on(document, 'keydown', ($event: KeyboardEvent) => {
            if ($event && $event.keyCode === 27 && this.viewList.length > 0) {
                const zIndex = this.$store.getters.getZIndex();
                if (zIndex !== this.zIndex) {
                    return;
                }
                this.refCloseView(this.viewList[this.viewList.length - 1], this.viewList.length - 1);
            }
        });
    }

    /**
     * 使用实例方法关闭视图
     *
     * @protected
     * @param {*} view
     * @param {number} i
     * @returns {*}
     * @memberof AppTopDrawer
     */
    protected refCloseView(view: any, i: number): any {
        const ref: any = this.$refs[view.viewname + i];
        if (ref) {
            if (view.dynamicProps) {
                this.closeModalData = [];
            }
            if (ref.$children[0] && ref.$children[0].closeView && ref.$children[0].closeView instanceof Function) {
                ref.$children[0].closeView();
            } else {
                ref.$listeners.close();
            }
        }
    }

    /**
     * 打开模态视图
     *
     * @param {*} [param={}]
     * @returns {Promise<any>}
     * @memberof AppTopDrawer
     */
    openModal(param: any = {}): Promise<any> {
        if (this.viewList.length === 0) {
            this.isShowDialogContainer = true;
        }
        return new Promise((resolve: (res: any) => void) => {
            if (!this.isShow) {
                this.$store.commit('upZIndex');
                this.zIndex = this.$store.getters.getZIndex();
                setTimeout(() => (this.isShow = true), 50);
            }
            this.viewList.push(Object.assign(param, { resolve }));
            this.showViewList.push(this.viewList[this.viewList.length - 1]);
            this.activeIndex = this.viewList.length - 1;
        });
    }

    /**
     * 关闭模态视图
     *
     * @memberof AppTopDrawer
     */
    closeView(item: any): void {
        this.isShowDialogContainer = false;
        if (this.closeModalData && this.closeModalData.length > 0 && this.closeModalData[0] !== undefined) {
            item.resolve({ ret: 'OK', datas: this.closeModalData });
        } else {
            item.resolve({ ret: '', datas: [] });
        }
        this.viewList.pop();
        this.activeIndex = this.viewList.length - 1;
        setTimeout(() => {
            this.showViewList.pop();
        }, 300);
        if (this.toBeClosedViews.length > 0) {
            const view: any = this.toBeClosedViews[this.toBeClosedViews.length - 1];
            const viewname: string = view.viewname;
            const i: number = view.index;
            this.toBeClosedViews.pop();
            this.refCloseView({ viewname }, i);
        }
    }

    /**
     * 关闭指定下标之前的所有页面
     *
     * @protected
     * @memberof AppTopDrawer
     */
    protected closeByIndex(i: number): void {
        this.toBeClosedViews = [];
        for (let index = i + 1; index < this.viewList.length - 1; index++) {
            this.toBeClosedViews.push({
                viewname: this.viewList[index].viewname,
                index: index,
            });
        }
        this.refCloseView(this.viewList[this.viewList.length - 1], this.viewList.length - 1);
    }

    /**
     * 绘制标题
     *
     * @protected
     * @returns {*}
     * @memberof AppTopDrawer
     */
    protected renderHeader(): any {
        return (
            <div class='studio-drawer-header'>
                <div class='studio-drawer-breadcrumb'>
                    <div class='studio-drawer-back' on-click={() => this.closeByIndex(this.viewList.length - 1)}>
                        <icon type='ios-arrow-back' />
                        {this.$t('components.drawer.back')}
                    </div>
                    {this.showViewList.map((item, i) => {
                        const ref: any = this.$refs[item.viewname + i];
                        if (!ref || !ref.$children || ref.$children.length <= 0) {
                            setTimeout(() => {
                                this.$forceUpdate();
                            }, 300);
                            return;
                        }
                        const title = ref.$children[0]?.model?.dataInfo
                            ? ref.$children[0]?.model?.dataInfo
                            : item.title;
                        return (
                            <span key={i}>
                                {i !== 0 ? <span class='studio-drawer-breadcrumb-item-separator'>&gt;</span> : null}
                                <span
                                    class={{ text: true, active: i === this.showViewList.length - 1 }}
                                    on-click={() => {
                                        if (this.showViewList.length === i + 1) {
                                            return;
                                        }
                                        this.closeByIndex(i);
                                    }}
                                >
                                    {title}
                                </span>
                            </span>
                        );
                    })}
                </div>
                {this.viewList.length > 1 ? (
                    <poptip
                        class='close'
                        confirm
                        placement='left-start'
                        title={this.$t('components.drawer.confirm')}
                        on-on-ok={() => this.closeByIndex(-1)}
                    >
                        <icon title={this.$t('components.drawer.close')} type='md-close' />
                    </poptip>
                ) : (
                    <div class='close' on-click={() => this.closeByIndex(-1)}>
                        <icon title={this.$t('components.drawer.close')} type='md-close' />
                    </div>
                )}
            </div>
        );
    }

    /**
     * 绘制视图
     *
     * @protected
     * @param {CreateElement} h
     * @returns {*}
     * @memberof AppTopDrawer
     */
    protected renderViews(h: CreateElement): any {
        return this.showViewList.map((view: any, i: number) => {
            try {
                const props: any = {
                    staticProps: { ...view.staticProps, viewDefaultUsage: false, noViewCaption: true },
                    dynamicProps: { ...view.dynamicProps },
                };
                const style: any = { 'z-index': i + 1, height: '100%' };
                return (
                    <div class={{ 'studio-drawer-item': true, active: this.activeIndex === i }}>
                        {h(view.viewname, {
                            key: view.viewname + i,
                            ref: view.viewname + i,
                            style,
                            props,
                            on: {
                                viewdataschange: (data: any) => {
                                    this.closeModalData = data;
                                },
                                close: () => {
                                    if (this.viewList.length - 1 < i) {
                                        return;
                                    }
                                    if (this.viewList.length === 1) {
                                        this.isShow = false;
                                        setTimeout(() => this.closeView(view), 500);
                                    } else {
                                        this.closeView(view);
                                    }
                                },
                                viewModelChange: () => {
                                    this.$forceUpdate();
                                },
                            },
                        })}
                    </div>
                );
            } catch (err) {
                LogUtil.warn(this.$t('components.drawer.close'), err);
            }
        });
    }

    /**
     * 绘制模态内容
     *
     * @returns {*}
     * @memberof AppTopDrawer
     */
    render(h: CreateElement): any {
        return (
            <div class='app-top-drawer' style={{ 'z-index': this.zIndex + 1 }}>
                <div
                    class='dialogContainer'
                    style={{ 'z-index': this.zIndex + 1, display: this.isShowDialogContainer ? 'block' : 'none' }}
                ></div>
                <div
                    class='studio-drawer'
                    key='studio-drawer'
                    style={{ 'z-index': this.zIndex, 'margin-top': this.isShow ? '0px' : '-100vh' }}
                >
                    {this.renderHeader()}
                    <div
                        class='studio-drawer-content'
                        style={`transform: translateX(${
                            this.activeIndex > 0 ? this.activeIndex * -100 : 0
                        }%) translateZ(0px);`}
                    >
                        {this.renderViews(h)}
                    </div>
                </div>
            </div>
        );
    }
}
