import { MovableArea, MovableView, View, ScrollView } from '@tarojs/components'
import './MoveOrderList.scss'
import { useEffect, useRef, useState } from 'react';
import { ColorType } from '@/context/themes/color';
import Taro from '@tarojs/taro';

export default function Component(props: { array: any, itemHeight: number }) {
    const [list, setList] = useState(props.array)
    const [movaleViewY, setMovaleViewY] = useState(0)
    const [dragElement, setDragElement] = useState(null)
    const [lastTarget, setLastTarget] = useState(null)
    const [startOffsetY, setStartOffsetY] = useState(0)
    const [startPageY, setStartPageY] = useState(0)
    const [dragIndex, setDragIndex] = useState(-1)
    const [scrollThreshold, setScrollThreshold] = useState(0.5)
    const upperThreshold = 100
    const lowThreshold = 100
    const [duration, setDuration] = useState(1000)
    const [canScroll, setCanScroll] = useState(true)
    const [changedIndex, setChangedIndex] = useState(-1)
    const [hiddenContent, setHiddenContent] = useState(false)

    const [scrollTop, setScrollTop] = useState(0)
    const [contentY, setContentY] = useState(0)
    const [contentHeight, setContentHeight] = useState(0)
    const ref = useRef(null)

    useEffect(() => {
        const query = Taro.createSelectorQuery();
        query.select('#myScrollView').boundingClientRect();
        query.exec((res) => {
            setContentY(res[0].top)
            setContentHeight(res[0].height)
        })
    }, [])

    function longPress(e, index) {
        setChangedIndex(index)
        setStartOffsetY(e.target.offsetTop)
        setStartPageY(e.touches[0].pageY)
        setDragIndex(index)
        setDragElement(list[index])
        setMovaleViewY(e.target.offsetTop)
        setCanScroll(false)
    }

    function touchMove(e) {
        if (dragElement) {
            let clientY = e.touches[0].clientY;
            pageScroll(clientY);
            let pageY = e.touches[0].pageY;
            let targetMoveDistance = pageY - startPageY
            let movaleViewY2 = startOffsetY + targetMoveDistance

            let targetIndex = computeFutureIndex(targetMoveDistance, dragIndex)
            if (targetIndex !== false && targetIndex != changedIndex) {
                var temps = swapListItems(list, targetIndex, changedIndex)
                setList(temps)
                setChangedIndex(targetIndex)

            }

            if (targetIndex === false && targetIndex != changedIndex) {
                var temps = swapListItems(list, dragIndex, changedIndex)
                setList(temps)
                setChangedIndex(dragIndex)
            }

            setMovaleViewY(movaleViewY2)
            setLastTarget(targetIndex as any)
            setHiddenContent(true)
        }
    }

    function pageScroll(clientY) {
        console.log(clientY,contentY,contentHeight)
        if ((clientY - contentY) + upperThreshold >= contentHeight) {
            // console.log('ccc',(clientY - contentY) + props.itemHeight);
            // var scroll = ref.current
            // debugger
            // (ref.current as any).scrollTo({scrollTop:100})
            // setScrollTop((clientY - contentY) + props.itemHeight)
            setScrollTop(2200)
            setCanScroll(true)
        }
        else if ((clientY - contentY) - lowThreshold <= 0) {
            setScrollTop((clientY - contentY) - props.itemHeight)
            setCanScroll(true)
        }
        else {
            setCanScroll(true)
        }
    }

    function swapListItems<T>(list: T[], index1: number, index2: number): T[] {
        const newList = [...list];
        const temp = newList[index1];
        newList[index1] = newList[index2];
        newList[index2] = temp;

        return newList;
    }


    function touchEnd(e) {
        if (dragElement) {
            // let pageY = e.changedTouches[0].pageY
            // let targetMoveDistance = pageY - startPageY;
            // let dragElementIndex = dragIndex;
            // const futrueIndex = computeFutureIndex(targetMoveDistance, dragElementIndex)
            // if (futrueIndex !== false) {
            //     var temps = list
            //     temps.splice(futrueIndex, 0, temps.splice(dragIndex, 1)[0])

            //     setList(temps)
            // }
            setDragElement(null)
            setLastTarget(null)
            setDragIndex(-1)

        }
        setChangedIndex(-1)
        setCanScroll(true)
        setHiddenContent(false)
    }

    function computeFutureIndex(targetMoveDistance, dragElementIndex) {
        let willInsertAfter = getSwapDirection(targetMoveDistance);
        if (willInsertAfter !== false) {
            /** 偏移索引 */
            let offsetElementIndex = dragElementIndex + willInsertAfter;
            /** 移动步数 */
            let step = targetMoveDistance / props.itemHeight;
            /** 步数补偿，当只有移动距离超过单项 _scrollThreshold 时才算有效 */
            if (step <= -1) {
                step += scrollThreshold;
            } else if (step >= 1) {
                step -= scrollThreshold;
            }
            /** 目标索引 */
            let futureIndex = parseInt(step) + offsetElementIndex;

            // 避免越界
            if (futureIndex < 0) {
                futureIndex = 0;
            } else if (futureIndex > list.length - 1) {
                futureIndex = list.length - 1;
            }

            return futureIndex;
        } else {
            return willInsertAfter;
        }
    }

    function getSwapDirection(targetMoveDistance) {
        if (Math.abs(targetMoveDistance) < props.itemHeight / 2) {
            // 轻轻拂动，滑动距离小于1/2单项高度
            return false;
        } else if (targetMoveDistance >= props.itemHeight / 2) {
            // console.log('[_getSwapDirection] 👇👇👇');
            return 1;  // 下滑
        } else if (targetMoveDistance <= props.itemHeight / -2) {
            // console.log('[_getSwapDirection] 👆👆👆');
            return -1;  // 上滑
        }
    }

    return <ScrollView id="myScrollView" ref={ref} scrollY={canScroll} style={{ height: 400 }} scrollTop={scrollTop}>
        <MovableArea style={{ height: list.length * props.itemHeight }}>
            {list.map((item, index) => {
                var className = 'demo_item'
                if (lastTarget == index) {
                    className += ' last_item'
                }

                if (dragIndex == index) {
                    className += ' drag_item'

                    // console.log(className)
                }
                return <View style={{ opacity: changedIndex == index && hiddenContent ? 0 : 1, height: props.itemHeight }}
                    className={className}
                    onLongPress={(e) => longPress(e, index)}
                    onTouchMove={(e) => touchMove(e)}
                    onTouchEnd={(e) => touchEnd(e)}
                >{item}</View>
            })}
            <MovableView style={{ height: props.itemHeight }}
                direction='vertical'
                disabled
                animation={false}
                y={movaleViewY}
            >
                <View className='demo_item' style={{ backgroundColor: ColorType.fast }}>
                    {dragElement}
                </View>
            </MovableView>
        </MovableArea>
    </ScrollView>
}