import { Grouper } from '@/lib/components/body/group';
import { IndexColumn } from '@/lib/types';
import {
    computed,
    defineComponent,
    h,
    nextTick,
    PropType,
    reactive,
    watch,
} from '@vue/composition-api';
import { fixStyle, flexWidth } from '../../utils/dom';
import { BOTTOM_SCROLL_HEIGHT } from '@/lib/constants/dom-fixed';
import './index.scss';
import { GroupPin } from '@/lib/types/group';
import { useStoreInject } from '@/lib/store';
import { emptyReason, RenderReason, setReason } from '@/lib/store/mark';
import {log} from "@/lib/utils/log";
// import { emptyReason, RenderReason, setReason } from '@/lib/store/mark';

export const GridBody = defineComponent({
    name: 'GridBody',
    props: {
        leftWidth: {
            require: true,
            type: Number,
        },
        rightWidth: {
            require: true,
            type: Number,
        },
        scrollWidth: {
            require: true,
            type: Number,
        },
        leftColumns: {
            require: true,
            type: Array as PropType<IndexColumn[]>,
        },
        rightColumns: {
            require: true,
            type: Array as PropType<IndexColumn[]>,
        },
        scrollColumns: {
            require: true,
            type: Array as PropType<IndexColumn[]>,
        },
        scrollLeft: {
            require: true,
            type: Number,
        },
        viewHeight: {
            require: true,
            type: Number,
        },
        contentHeight: {
            require: true,
            type: Number,
        },
    },
    emits: ['contextmenu', 'verticalScroll', 'horizontalScroll', 'cellClick', 'cellDbClick'],
    setup(props, ctx) {
        watch(
            () => props.scrollLeft,
            (left: number) => {
                (ctx.refs['scroll'] as Element).scrollLeft = left;
            },
        );

        const store = useStoreInject();
        const activeRowIds = reactive<string[]>([]);
        // 筛选 排序 树展开收起 触发
        watch(
            () => store.state.view.rowIndex2Id,
            () => {
                const { startIndex, endIndex } = store.state.virtualScroll.y;
                activeRowIds.length = 0;
                activeRowIds.push(...store.state.view.rowIndex2Id.slice(startIndex, endIndex));
            },
        );
        // 滚动触发
        watch(
            () => store.state.virtualScroll.y,
            ({ startIndex, endIndex }) => {
                activeRowIds.length = 0;
                activeRowIds.push(...store.state.view.rowIndex2Id.slice(startIndex, endIndex));
                setReason(RenderReason.preRender);
                nextTick(() => emptyReason());
            },
        );
        const onContextmenu = (e: PointerEvent) => {
            e.preventDefault();
            ctx.emit('contextmenu', e);
        };
        return {
            // 事件
            onBodyClick: (e: PointerEvent) => ctx.emit('cellClick', e),
            onDbClick: (e: PointerEvent) => ctx.emit('cellDbClick', e),
            onContextmenu,
            onVerticalScroll: (e: PointerEvent) => ctx.emit('verticalScroll', e),
            onHorizontalScroll: (e: PointerEvent) => ctx.emit('horizontalScroll', e),
            // 激活区域
            leftSelectionArea: computed(() => store.state.selectionStatus.leftArea),
            rightSelectionArea: computed(() => store.state.selectionStatus.rightArea),
            scrollSelectionArea: computed(() => store.state.selectionStatus.scrollArea),
            leftCalculatingArea: computed(() => store.state.dragCalculateStatus.leftArea),
            rightCalculatingArea: computed(() => store.state.dragCalculateStatus.rightArea),
            scrollCalculatingArea: computed(() => store.state.dragCalculateStatus.scrollArea),
            activeStatus: computed(() => store.state.activeStatus),
            // 激活 ID
            activeRowIds,
        };
    },
    render() {
        log('[render]body render');

        const {
            viewHeight,
            contentHeight,
            onBodyClick,
            onDbClick,
            onContextmenu,
            onVerticalScroll,
            onHorizontalScroll,
            activeRowIds,

            leftColumns,
            rightColumns,
            scrollColumns,

            leftWidth,
            rightWidth,
            scrollWidth,

            leftSelectionArea,
            rightSelectionArea,
            scrollSelectionArea,
            leftCalculatingArea,
            rightCalculatingArea,
            scrollCalculatingArea,
            //
            activeStatus,
        } = this;

        const getGroupStyle = (width: number) =>
            fixStyle({ ...flexWidth(width), height: contentHeight });
        const scrollBoxHeight = `calc(100% + ${BOTTOM_SCROLL_HEIGHT}px)`;

        const getActiveCell = (pin: GroupPin) => {
            return {
                clickedCell:
                    activeStatus.clickedBodyCell?.pin === pin
                        ? activeStatus.clickedBodyCell
                        : null,
                dbClickedCell:
                    activeStatus.dbClickedBodyCell?.pin === pin
                        ? activeStatus.dbClickedBodyCell
                        : null,
            };
        };
        const { clickedCell: leftClickedCell, dbClickedCell: leftDbClickedCell } = getActiveCell(
            GroupPin.left,
        );
        const { clickedCell: scrollClickedCell, dbClickedCell: scrollDbClickedCell } =
            getActiveCell(GroupPin.scroll);
        const { clickedCell: rightClickedCell, dbClickedCell: rightDbClickedCell } = getActiveCell(
            GroupPin.right,
        );
        return (
            <div
                class={'grid-body gridable-scroll'}
                style={fixStyle({
                    height: viewHeight,
                })}
                onClick={onBodyClick}
                onDblclick={onDbClick}
                onContextmenu={onContextmenu}
                onScroll={onVerticalScroll}
            >
                <div class={'grid-panel pin-left'} style={getGroupStyle(leftWidth)}>
                    {leftColumns.length > 0 ? (
                        <Grouper
                            key={'left'}
                            pin={GroupPin.left}
                            columns={leftColumns}
                            width={leftWidth}
                            activeRowIds={activeRowIds}
                            selectionArea={leftSelectionArea}
                            calculatingArea={leftCalculatingArea}
                            clickedCell={leftClickedCell}
                            dbClickedCell={leftDbClickedCell}
                        />
                    ) : null}
                </div>
                <div class={'grid-panel scroll'} style={fixStyle({ height: contentHeight })}>
                    <div
                        ref='scroll'
                        class={'scroll-content-box gridable-scroll'}
                        style={{ height: scrollBoxHeight }}
                        onScroll={onHorizontalScroll}
                    >
                        <div class={'scroll-content'} style={getGroupStyle(scrollWidth)}>
                            {scrollColumns.length > 0 ? (
                                <Grouper
                                    key={'scroll'}
                                    pin={GroupPin.scroll}
                                    columns={scrollColumns}
                                    width={scrollWidth}
                                    activeRowIds={activeRowIds}
                                    selectionArea={scrollSelectionArea}
                                    calculatingArea={scrollCalculatingArea}
                                    clickedCell={scrollClickedCell}
                                    dbClickedCell={scrollDbClickedCell}
                                />
                            ) : null}
                        </div>
                    </div>
                </div>

                <div class={'grid-panel pin-right'} style={getGroupStyle(rightWidth)}>
                    {rightColumns.length > 0 ? (
                        <Grouper
                            key={'right'}
                            pin={GroupPin.right}
                            columns={rightColumns}
                            width={rightWidth}
                            activeRowIds={activeRowIds}
                            selectionArea={rightSelectionArea}
                            calculatingArea={rightCalculatingArea}
                            clickedCell={rightClickedCell}
                            dbClickedCell={rightDbClickedCell}
                        />
                    ) : null}
                </div>
            </div>
        );
    },
});
