import styles from './style.module.css'
import { useEffect, useState, useRef, useContext } from 'react'
import AppContext from '@/components/hooks/createContext'
import { getShowCase } from '@/pages/api/base'
import React from 'react'
import Detail from '../Detail'
import { useTranslation } from 'next-i18next'
import Item from '../Item'
import { IS_ONLY_SHOW_STAR } from '@/common/constans/international'

const containerWidth = 252

interface Iprops {
    activeTab: string
    setShowTab: (value: boolean) => void
}
const WaterFall = ({ activeTab, setShowTab }: Iprops) => {
    const { t } = useTranslation('studio')
    const {
        agentName: [agentName],
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    } = useContext(AppContext)!

    const [cols, setCols] = useState(-1)
    const [feedHeightArr, setFeedHeightArr] = useState<number[]>([])
    const [list, setList] = useState([])
    const [lastInsertIndex, setLastInsertIndex] = useState<number>(0)
    const [renderIndex, setRendeIndex] = useState(-1)
    const isRendering = useRef(false)
    const [feedListArr, setFeedListArr] = useState<any[]>([])
    const page = useRef(1)
    const offset = useRef(0)
    const [show, setShow] = useState(false)
    const [showDetail, setShowDetail] = useState(false)
    const [detailInfo, setDetailInfo] = useState<any>()
    const isRequestCompleted = useRef(true)
    const lastScrollTop = useRef(-1)
    const isEnd = useRef(false)
    const isCanScroll = useRef(false)

    const [unStars, setUnStars] = useState<string[]>([])

    useEffect(() => {
        const winWidth =
            document.documentElement.clientWidth || document.body.clientWidth || window.innerWidth
        const wallWidth = winWidth - 440
        const cols = Math.floor(wallWidth / (containerWidth + 16))
        if (cols > 0) {
            const arr = Array(cols).fill([])
            setFeedListArr(arr)
            setCols(cols)
        }
    }, [])

    const jumpToDetail = (data: any) => {
        setDetailInfo(data)
        setShowDetail(true)
    }

    useEffect(() => {
        const element = document.getElementById('output')
        if (cols >= 0) {
            getData()
            element?.addEventListener('scroll', handleScroll) // 绑定滚动事件
        }

        return () => {
            element?.removeEventListener('scroll', handleScroll) // 在组件卸载时解绑滚动事件
        }
    }, [cols])

    useEffect(() => {
        if (renderIndex < 0) return
        requestAnimationFrame(renderFeed)
    }, [renderIndex])

    const getData = async () => {
        if (!agentName) return
        isRequestCompleted.current = false
        const value = await getShowCase({
            agentName,
            page: page.current,
            tag: activeTab,
            offset: page.current === 1 ? 0 : offset.current,
        })
        setShow(true)
        if (page.current === 1) {
            setUnStars([])
        }
        page.current = page.current + 1
        setList((prevList) => prevList.concat(value?.list || []))
        isEnd.current = value?.isEnd
        isRequestCompleted.current = true
    }

    useEffect(() => {
        if (IS_ONLY_SHOW_STAR) setShowTab(list?.length > 0)
        if (list.length > 0 && isRequestCompleted.current) {
            renderFeed()
        }
    }, [list])

    // feed渲染
    const renderFeed = () => {
        if (list.length === 0 || renderIndex >= list.length - 1 || isRendering.current) {
            isCanScroll.current = true
            return
        }
        isRendering.current = true
        isCanScroll.current = false

        if (!feedHeightArr.length) {
            for (let i = 0; i < cols; i++) {
                const height = document.getElementById(`item_coloum_${i}`)?.offsetHeight || 0
                feedHeightArr.push(height)
            }
        } else {
            feedHeightArr[lastInsertIndex] =
                document.getElementById(`item_coloum_${lastInsertIndex}`)?.offsetHeight || 0
        }
        setFeedHeightArr([...feedHeightArr])
    }

    useEffect(() => {
        if (!feedHeightArr.length) return
        const minHeight = Math.min.apply(null, feedHeightArr)
        getMinhIndex(feedHeightArr, minHeight).then((min) => {
            const last = parseInt(String(min), 10)
            const feedData = list[renderIndex + 1]
            feedListArr[last] = feedListArr[last].concat({
                i: renderIndex + 1,
                data: feedData,
                top: minHeight + 24,
            })

            setLastInsertIndex(last)
            setFeedListArr([...feedListArr])
            setRendeIndex(renderIndex + 1)
            isRendering.current = false
        })
    }, [feedHeightArr])

    // 最小高度的列数索引
    const getMinhIndex = (arr: number[], value: number) => {
        return new Promise<number>((resolve) => {
            let minIndex = 0
            for (const i in arr) {
                if (arr[i] === value) {
                    minIndex = parseInt(i, 10)
                    resolve(minIndex)
                }
            }
        })
    }

    const handleScroll = () => {
        const element = document.getElementById('output')
        // 当前滚动条高度
        const scrollTop = element?.scrollTop || 0

        // 底部检测高度
        const bottom = document.getElementById('bottomDetection')
        if (!bottom) return
        const bottomDetectionTop = bottom.offsetTop
        const tempLastScrollTop = lastScrollTop.current
        lastScrollTop.current = scrollTop

        if (scrollTop > tempLastScrollTop) {
            const wallHeight =
                document.documentElement.clientHeight ||
                document.body.clientHeight ||
                window.innerHeight
            if (
                bottomDetectionTop - tempLastScrollTop < wallHeight * 1.5 &&
                !isRendering.current &&
                !isEnd.current &&
                isRequestCompleted.current &&
                isCanScroll.current
            ) {
                requestAnimationFrame(getData)
            }
        }
    }

    const starCallback = (unitId: string, isStar: boolean) => {
        if (isStar) {
            setUnStars((preState) => preState.filter((it) => it != unitId))
        } else {
            setUnStars((preState) => preState.concat([unitId]))
        }
    }

    useEffect(() => {
        offset.current = -unStars.length
    }, [unStars])

    return (
        <div
            className={`${styles.waterfall} ${
                IS_ONLY_SHOW_STAR ? (list?.length ? '' : styles.noData) : ''
            }`}
        >
            <div className={styles.showCaseWrap}>
                <div className={styles.wrap} style={{ width: cols * (containerWidth + 16) + 'px' }}>
                    <div className={styles.clearfix}>
                        {feedListArr.map((i, key) => {
                            return (
                                <div className={styles.column} key={key} id={`item_coloum_${key}`}>
                                    {i.map((item: any, index: number) => {
                                        return (
                                            <React.Fragment key={index}>
                                                {item?.data?.showImage ? (
                                                    <Item
                                                        data={item?.data}
                                                        containerWidth={containerWidth}
                                                        jumpToDetail={jumpToDetail}
                                                        showOpreate={activeTab === 'star'}
                                                        unStars={unStars}
                                                        starCallback={starCallback}
                                                        dataChange={(data) => {
                                                            setFeedListArr((preState) =>
                                                                preState.map((pi, pkey) => {
                                                                    if (key === pkey) {
                                                                        return pi.map((it) =>
                                                                            it?.data?.id == data.id
                                                                                ? { ...it, data }
                                                                                : it,
                                                                        )
                                                                    } else {
                                                                        return pi
                                                                    }
                                                                }),
                                                            )
                                                        }}
                                                    ></Item>
                                                ) : null}
                                            </React.Fragment>
                                        )
                                    })}
                                </div>
                            )
                        })}
                    </div>
                    {show ? (
                        <div className={`ag14 ${styles.empty}`} id="bottomDetection">
                            {isEnd.current
                                ? !feedHeightArr?.length && activeTab === 'star'
                                    ? IS_ONLY_SHOW_STAR
                                        ? ''
                                        : t('emptyStar')
                                    : ''
                                : t('loading')}
                        </div>
                    ) : null}
                </div>
            </div>
            {showDetail ? (
                <Detail
                    setShowDetail={setShowDetail}
                    id={detailInfo.id}
                    showDetail={showDetail}
                    tag={activeTab}
                    isSubmitted={detailInfo.isSubmitted}
                    setSubmitted={(submitted) => {
                        const data = { ...detailInfo, isSubmitted: submitted }
                        setDetailInfo(data)
                        setFeedListArr((preState) =>
                            preState.map((pi) => {
                                return pi.map((it) =>
                                    it?.data?.id == data.id ? { ...it, data } : it,
                                )
                            }),
                        )
                    }}
                ></Detail>
            ) : null}
        </div>
    )
}

export default WaterFall
