import { computed, defineComponent, onMounted } from '@vue/composition-api';
import { GridHeader } from './header';
import { GridBody } from './body';
import { RightMenu } from './right-menu';
import { useScroll } from '@/lib/services/scroll';
import { useMouseDown } from '@/lib/services/mouse-dwon';
import { useBodyClick } from '@/lib/services/body-click';
import { useInitialize } from '@/lib/services/initialize';
import { BottomScroll } from '@/lib/components/bottom-scroll';
import { BottomBar } from '@/lib/components/bottom-bar';
import { useCopySelection } from '@/lib/services/clipboard';
import { useStoreProvide } from '@/lib/store';
import { usePublicApi } from '@/lib/api';
import { props } from '@/lib/props';
import { BOTTOM_TOTAL_BAR_HEIGHT } from '@/lib/constants/dom-fixed';
import { Operator } from '@/lib/operator';
import { GridProp } from '@/lib/types';
import { log } from '@/lib/utils/log';

export const Grid = defineComponent({
    props,
    setup(props: Readonly<GridProp>, ctx) {
        const { rowHeight: propRowHeight, height: propHeight, width: propWidth } = props;
        const getGirdDom = () => ctx.refs['gridDom'] as Element;
        const getGirdDody = () => ctx.refs['gridBody'] as any;
        const getMenuDom = () => document.getElementById('menuDom');

        const { store, operators } = useStoreProvide();

        const { initOuterSize, calculateDataAndInnerSize, addResizeMonitor, syncFeature } =
            useInitialize(store, operators);

        onMounted(() => {
            operators[Operator.layout].registerBodyContainer(getGirdDody().$el);
            operators[Operator.layout].registerGridContainerDom(getGirdDom().parentElement);

            initOuterSize(propHeight, propWidth, propRowHeight);
            // 调用顺序规划
            syncFeature(props);
            calculateDataAndInnerSize(props);

            addResizeMonitor();
        });

        const { vertical, horizontal } = useScroll(store);

        const copySelection = useCopySelection(store);

        const { click, dbClick, contextMenu } = useBodyClick(store, getGirdDom, getMenuDom);

        const api = usePublicApi(store, operators);

        return {
            api,
            // 事件
            onCellClick: click,
            onCellDbClick: dbClick,
            onVerticalScroll: vertical(),
            onHorizontalScroll: horizontal(),
            onMouseDown: useMouseDown(store, operators)(),
            onBodyContextmenu: contextMenu,
            onCopySelection: () => copySelection(),
            onCopySelectionWithColumn: () => copySelection(true),
            // 样式
            config: computed(() => store.state.config),
            // 虚拟滚动
            virtualScroll: computed(() => store.state.virtualScroll),
            // 右侧菜单
            rightMenuStatus: computed(() => store.state.rightMenu),
            // 区块位置
            leftWidth: computed(() => store.state.index.columnGroupRecord.left.width),
            rightWidth: computed(() => store.state.index.columnGroupRecord.right.width),
            scrollWidth: computed(() => store.state.index.columnGroupRecord.scroll.width),
            // 区块所属列
            leftColumns: computed(() =>
                store.state.index.columnGroupRecord.left.ids.map(
                    (id) => store.state.index.columnRecord[id],
                ),
            ),
            rightColumns: computed(() =>
                store.state.index.columnGroupRecord.right.ids.map(
                    (id) => store.state.index.columnRecord[id],
                ),
            ),
            scrollColumns: computed(() => {
                return store.state.index.columnGroupRecord.scroll.ids.map(
                    (id) => store.state.index.columnRecord[id],
                );
            }),
        };
    },
    methods: {
        getApi() {
            return this.api;
        },
    },
    render() {
        const {
            config,
            rightMenuStatus,
            onCellDbClick,
            onCellClick,
            onCopySelection,
            onCopySelectionWithColumn,
            onVerticalScroll,
            onHorizontalScroll,
            onBodyContextmenu,
            onMouseDown,
            virtualScroll,
            leftWidth,
            rightWidth,
            scrollWidth,
            leftColumns,
            rightColumns,
            scrollColumns,
        } = this;
        log('[render] container');

        return (
            <div
                ref='gridDom'
                class={'grid-table'}
                style={{ height: `${config.height}px`, width: `${config.width}px` }}
                onMousedown={onMouseDown}
            >
                <GridHeader
                    leftWidth={leftWidth}
                    rightWidth={rightWidth}
                    scrollWidth={scrollWidth}
                    leftColumns={leftColumns}
                    rightColumns={rightColumns}
                    scrollColumns={scrollColumns}
                    scrollLeft={virtualScroll.xStartLeft}
                    rowHeight={config.rowHeight}
                    rowLevel={config.headerGroupLevel}
                    height={config.headerHeight}
                />
                <GridBody
                    ref='gridBody'
                    leftWidth={leftWidth}
                    rightWidth={rightWidth}
                    scrollWidth={scrollWidth}
                    leftColumns={leftColumns}
                    rightColumns={rightColumns}
                    scrollColumns={scrollColumns}
                    onContextmenu={onBodyContextmenu}
                    onVerticalScroll={onVerticalScroll}
                    onHorizontalScroll={onHorizontalScroll}
                    onCellDbClick={onCellDbClick}
                    onCellClick={onCellClick}
                    scrollLeft={virtualScroll.xStartLeft}
                    viewHeight={config.bodyViewHeight}
                    contentHeight={config.bodyHeight}
                />
                <BottomBar
                    leftWidth={leftWidth}
                    rightWidth={rightWidth}
                    scrollWidth={scrollWidth}
                    leftColumns={leftColumns}
                    rightColumns={rightColumns}
                    scrollColumns={scrollColumns}
                    scrollLeft={virtualScroll.xStartLeft}
                    height={BOTTOM_TOTAL_BAR_HEIGHT}
                />
                <BottomScroll
                    leftWidth={leftWidth}
                    rightWidth={rightWidth}
                    scrollWidth={scrollWidth}
                    onScroll={onHorizontalScroll}
                    scrollLeft={virtualScroll.xStartLeft}
                />
                {rightMenuStatus.active ? (
                    <RightMenu
                        top={rightMenuStatus.top}
                        left={rightMenuStatus.left}
                        options={[
                            {
                                title: '复制',
                                command: 'Ctrl+C',
                                executor: onCopySelection,
                            },
                            {
                                title: '带表头复制',
                                executor: onCopySelectionWithColumn,
                            },
                        ]}
                    />
                ) : null}
            </div>
        );
    },
});
