import useCopy from "@/Hook/useCopy"
import React, { useCallback, useEffect, useState } from "react"
import { Carousel, Image, message, Pagination, Popconfirm, Spin } from 'antd'
import style from './index.less'
import FileModal from './components/fileModal'
import { useModel } from "umi"
import ImgModal from "./components/imgModal"
import TreeBox from "./components/tree"
import SortModal from "./components/fileModal/sortModal"
import { EyeOutlined } from "@ant-design/icons"
import ImgsModal from "./components/imgsModal"
import MoveTo from "./components/moveTo"
import VideoNews from "@/pages/launchSystemNew/components/newsModal/videoNews"
import { getVideoImgUrl } from "@/utils/utils"
import useFileDrop from "@/Hook/useFileDrop"
import { RcFile } from "antd/lib/upload"
import UploadsTable from "./components/uploadsTable"
import Migrate from "./components/Migrate"

interface News {
    id: number,
    sysMediaId: number,
    sortIndex: number,
    title: string,
    thumbUrl: string,
    author: string,
    digest: string,
    showCoverPic: boolean,
    content: string,//内容只在调取详情时获取
    contentSourceUrl: string,//文章地址
    needOpenComment: boolean,
    onlyFansCanComment: boolean
}
interface Item {
    id: number,
    folder: boolean,//是否是文件夹
    mediaType: 'VIDEO' | 'IMG' | 'PAGE',//类型
    number: string,//编号
    title: string,//名称
    url: string,//链接
    belongType: string,//所属类型
    createTime: string,//创建时间
    description: string,//k图文描述
    news?: News[]//图文内容
    knewsThumbUrl: string, // 图片链接
    knewsThumbId: number,//本地图片ID
    knewsThumbInfo: any,//k客服详情
    videoTitle: string,//视频标题
    width: number, // 宽
    height: number,  // 高
    pageSpecsList?: any[],
}
interface Props {
    isAll?: boolean,//是否允许全选默认开启
    height?: any,//当使用为弹窗组件时设置高度以免太高
    noFile?: boolean,//是否禁止选择文件夹
    setPage?: (type: 0 | 1 | 2 | 3, data?: any) => void, // 0 创建 1 查看 2 复制
    isBack?: boolean,  // 是否需要回填
}
function FlieBox(props: Props) {

    const { isAll = true, height, noFile = false, setPage, isBack = false } = props
    const { state, set, dels, list, get, onFile, allFile, delPupOn, delPupOff, changeClickFile, editFile, fileClick, treeClick, pathClick, getList, edit_media_folder, get_folder_tree } = useModel(isAll ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
    const { fileVisible, belongUser, selectFile, selectItem, delPupId, xy, rightClickPup, path, publicPath, parentId, imgVisrible, imgsVisrible, mediaType, sortVisible, num } = state
    const { copy } = useCopy()
    const fileImg = require('../../../public/file.png')
    const [moveId, setMoveId] = useState<any>('')//移动的素材ID
    const [treeEl, item, folderId, setActionId, setHoverId] = TreeBox({ data: get_folder_tree.data, belongUser })
    const [listData, setListData] = useState<any>({})
    const [showImg, setShowImg] = useState(-1)

    /********************************/
    let moveSelected = document.getElementById("moveSelected"); // 选区
    let fileContent = document.getElementById("file_content"); // 内容区
    const [startPoint, setStartPoint] = useState({ x: 0, y: 0, flag: false }); // 记录鼠标开始按下坐标 flag 是否开启拖拽
    const [isSelect, setIsSelect] = useState<boolean>(false)  // 记录是否框选过素材
    const [sourceList, setSourceList] = useState<any>({})
    const [moveShow, setMoveShow] = useState<boolean>(false)
    const [migrateSc, setMigrateSc] = useState<boolean>(false)
    /********************************/

    // 处理数据
    useEffect(() => {
        let newList: any = {}
        listData?.records?.forEach((item: { id: number }) => {
            newList[item.id] = JSON.parse(JSON.stringify(item))
        })
        setSourceList(newList)
    }, [listData?.records])

    // 获取数据
    useEffect(() => {
        setListData(list?.data)
    }, [list, mediaType])

    /**复制编号 */
    const copyId = useCallback((e: React.MouseEvent<HTMLSpanElement, MouseEvent>, value: string) => {
        e.stopPropagation()//阻止冒泡传递到文件夹被点击事件
        copy(value)
    }, [])

    /**全局右键菜单 */
    const Menu = useCallback((props: { isItem?: boolean }) => {
        if (props.isItem && isAll) {
            return <ul style={{ top: xy?.y, left: xy?.x }} className={style.menu} >
                {(isAll || num === 100) && <li onClick={() => allFile('xz')}>全选</li>}
                {(isAll || num === 100) && listData?.records && listData?.records?.some((item: { id: number }) => selectFile?.includes(item.id)) && <li onClick={() => allFile('qx')} style={{ color: 'red' }}>取消选择</li>}
                {(isAll && selectItem?.length > 0 && ['IMG', 'VIDEO'].includes(mediaType || '') && selectItem.every((item: any) => !item.folder)) && <li onClick={() => { setMigrateSc(true) }} style={{ color: 'red' }}>迁移素材</li>}
                {mediaType === 'PAGE' && !rightClickPup.folder ? <>
                    {/* <li onClick={() => { setPage && setPage(1, rightClickPup.id) }}>查看</li> */}
                    <li onClick={() => { setPage && setPage(2, rightClickPup.id) }}>复制</li>
                    <li onClick={() => { setPage && setPage(3, rightClickPup.id) }}>批量复制</li>
                </> : <>
                    <li onClick={() => { editFile() }}>编辑</li>
                </>}
                {mediaType !== 'PAGE' && !rightClickPup.folder && <li onClick={() => { copy(rightClickPup?.url) }}>复制链接</li>}
                <li onClick={() => { set({ actionItem: rightClickPup, sortVisible: true }) }}>编辑排序</li>
                <li onClick={() => { set({ fileVisible: true }) }}>新建文件夹</li>
                <li onClick={() => { set({ imgVisrible: true }) }}>新建素材</li>
                {isAll && selectFile && selectFile?.length > 0 && <li onClick={() => { setMoveShow(true) }}>移动至</li>}
                <li onClick={(e) => { delPupOn(rightClickPup.id); onFile(e, rightClickPup, isAll, true) }} style={{ color: 'red' }}>删除</li>
                {isAll && selectFile && selectFile?.length > 0 && <li onClick={dels} style={{ color: 'red' }}>删除选中文件</li>}
            </ul>
        }
        return <ul style={{ top: xy?.y, left: xy?.x }} className={style.menu}>
            {(isAll || num === 100) && <li onClick={() => allFile('xz')}>全选</li>}
            {(isAll || num === 100) && listData?.records && listData?.records?.some((item: { id: number }) => selectFile?.includes(item.id)) && <li onClick={() => allFile('qx')} style={{ color: 'red' }}>取消选择</li>}
            {(isAll && selectItem?.length > 0 && ['IMG', 'VIDEO'].includes(mediaType || '') && selectItem.every((item: any) => !item.folder)) && <li onClick={() => { setMigrateSc(true) }} style={{ color: 'red' }}>迁移素材</li>}
            {//防止K图文无限嵌套创建判断
                (isAll !== false) && <li onClick={() => { set({ fileVisible: true }) }}>新建文件夹</li> //: <li>此处无法新建操作</li>
            }
            {mediaType === 'PAGE' ? isAll ? <li onClick={() => { setPage && setPage(0) }}>新建素材</li> : <li>此处无法新建操作</li> : <li onClick={() => { set({ imgVisrible: true }) }}>新建素材</li>}
            {mediaType === 'IMG' && <li onClick={() => { set({ imgsVisrible: true }) }}>批量新建素材</li>}
            {isAll && selectFile && selectFile?.length > 0 && <li onClick={dels} style={{ color: 'red' }}>删除选中文件</li>}
        </ul>
    }, [xy, rightClickPup, allFile, mediaType])
    /**鼠标右键 */
    const rightMenu = useCallback((e: any, isItem?: any) => {
        e.stopPropagation()
        e.preventDefault()
        let x = e.clientX;
        let y = e.clientY;
        set({ xy: { x, y } })
        if (isItem) {
            set({ rightClickPup: isItem })
        } else {
            set({ rightClickPup: { id: 'all' } })
        }
        return false;
    }, [])
    /**左键点击页面隐藏菜单 */
    useEffect(() => {
        function fnc(e: any) {
            set({ rightClickPup: { id: '' } })
        }
        document.addEventListener('click', fnc)
        return () => {
            document.removeEventListener('click', fnc)
        }
    }, [])
    // /**切换个人|公共|父目录ID变化清空选中的文件*/
    useEffect(() => {
        if (!isBack) {
            set({ selectFile: [], selectItem: [] })
        }
        if (belongUser == '1' && path) {//处理切换个人|公共时保留路径层级的请求
            set({ parentId: path[path?.length - 1]?.id || null })
        }
        if (belongUser == '0' && publicPath) {
            set({ parentId: publicPath[publicPath?.length - 1]?.id || null })
        }
    }, [belongUser, parentId, path?.length, publicPath?.length])
    /**卸载组件处理 */
    useEffect(() => {
        return () => {
            set({ parentId: null })
        }
    }, [])
    /**获取目录树*/
    useEffect(() => {
        get_folder_tree.run({ belongUser, mediaType })
    }, [isAll, mediaType, belongUser])
    // 点击目录树进入对应目录
    useEffect(() => {
        if (item) {
            let { icon, children, ...arg } = item
            treeClick(arg)
        }
    }, [item])
    // 拖动事件配置
    const moveConfig = useCallback((item: any) => {
        return {
            draggable: true,
            onDragStart: (ev: any) => {
                console.log('---->', ev)
                let img = document.createElement('img')
                img.src = fileImg;
                ev.dataTransfer.setDragImage(img, 0, 0)
                console.log('item---->', item)
                setMoveId(item.id)
            },
            onDragEnd: (e: any) => {
                if (folderId !== '' && moveId !== '') {
                    edit_media_folder.run({ sysMediaId: moveId, folderId, mediaType }).then(res => {
                        message.success('操作成功')
                        list.refresh()
                    })
                }
                setActionId('')
                setHoverId('')
                setMoveId('')
            },
        }
    }, [folderId, moveId, mediaType])

    /** 判断2个元素是否重合 */
    const elementsOverlap = (el1: HTMLElement, el2: HTMLElement) => {
        const domRect1 = el1.getBoundingClientRect();
        const domRect2 = el2.getBoundingClientRect();
        return !(
            domRect1.top > domRect2.bottom ||
            domRect1.right < domRect2.left ||
            domRect1.bottom < domRect2.top ||
            domRect1.left > domRect2.right
        );
    }

    /**记录鼠标down event */
    const onMouseDown = ({ target: { dataset }, pageX, pageY }: any) => {
        const { type } = dataset
        if (isBack && num !== 100) return
        if (moveSelected && type === 'right-boxzones') {
            moveSelected.style.top = pageY + 'px';
            moveSelected.style.left = pageX + 'px';
            setStartPoint({ x: pageX, y: pageY, flag: true })
        }
    }

    /**记录鼠标抬起事件 */
    const onMouseUp = () => {
        if (startPoint.flag && moveSelected) {
            setStartPoint({ x: 0, y: 0, flag: false })
            moveSelected.style.width = '0px';
            moveSelected.style.height = '0px';
            moveSelected.style.top = '0px';
            moveSelected.style.left = '0px';
            moveSelected.style.bottom = '0px';
            moveSelected.style.right = '0px';
        }
    }
    /** 鼠标移动事件 */
    const onMouseMove = ({ pageX, pageY }: any) => {
        const { x, y, flag } = startPoint
        if (flag) {
            if (moveSelected) {
                if (pageX < x) { //表示左移
                    moveSelected.style.left = pageX + 'px';
                    moveSelected.style.width = (x - pageX) + 'px'; //向左移动的距离作为选区的宽
                } else {
                    moveSelected.style.width = (pageX - x) + 'px';
                }
                if (pageY < y) { //向上移动
                    moveSelected.style.top = pageY + 'px';
                    moveSelected.style.height = (y - pageY) + 'px';
                } else {
                    moveSelected.style.height = (pageY - y) + 'px';
                }
                //通过得到的left和top加上元素自身的宽高来计算选区的right和bottom
                moveSelected.style.bottom = Number(moveSelected.style.top.split('px')[0]) + Number(moveSelected.style.height.split('px')[0]) + 'px';
                moveSelected.style.right = Number(moveSelected.style.left.split('px')[0]) + Number(moveSelected.style.width.split('px')[0]) + 'px';

                if (fileContent && fileContent?.children?.length > 0) {
                    //找出选中的区域并激活
                    let checkboxs: any = fileContent?.children
                    for (let i = 0; i < checkboxs?.length; i++) {
                        let id = checkboxs[i]?.getAttribute('data-id')
                        if (elementsOverlap(moveSelected, checkboxs[i]) && id) {
                            id = Number(id)
                            let state = selectFile?.some((i) => i === id)
                            if (!state) {//新增
                                setIsSelect(true)
                                set({ selectFile: [...selectFile as number[], id] })
                                if (isBack) {
                                    set({ selectItem: [...selectItem, sourceList[id]] })
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    /** 鼠标离开可拖动区域事件 */
    const onMouseLeave = () => {
        if (startPoint.flag && moveSelected) {
            setStartPoint({ x: 0, y: 0, flag: false })
            moveSelected.style.width = '0px';
            moveSelected.style.height = '0px';
            moveSelected.style.top = '0px';
            moveSelected.style.left = '0px';
        }
    }


    // 获取拖拽的文件
    const [fileList, setFileList] = useState<FileList>()
    const [uploadVisible, setUploadVisible] = useState<boolean>(false)
    const { isDragOver, dropAreaProps } = useFileDrop((fileList) => {
        if (!moveId) {
            setFileList(fileList)
            setUploadVisible(true)
        }
    });

    return <div style={{ display: 'flex', flexFlow: 'row', width: '100%', padding: get_folder_tree?.data?.length ? 0 : '0 16px 0' }}>
        {get_folder_tree?.data?.length > 0 && <div style={{ flexShrink: 0 }}>
            {treeEl}
        </div>}
        <div
            style={{ flex: 1, padding: '10px 0px 0px' }}
            data-type="right-boxzones"
            onMouseDown={onMouseDown}
            onMouseUp={onMouseUp}
            onMouseLeave={onMouseLeave}
            onMouseMove={onMouseMove}
            onDoubleClick={() => {
                if (isSelect) {
                    set({ selectItem: [] }); set({ selectFile: [] })
                }
            }}
        >
            <div
                className={style.files}
                data-type="right-boxzones"
                onContextMenu={rightMenu}
                style={height ? { height } : {}}
                {...(mediaType !== 'PAGE' ? dropAreaProps : {})}
            >
                {mediaType !== 'PAGE' && isDragOver && !moveId && <div className={`${style.placeholder} ${isDragOver ? style.dragOver : ''}`}><span>拖动文件到这里</span></div>}
                {/* 层级路径 */}
                <div className={style.path} >
                    {//存在渲染个人本地路径不存在执行公共本地
                        belongUser == '1' && path?.map((item: { title: string }, index: number) => {
                            return <span key={index} onClick={() => { pathClick({ ...item, index }) }} >
                                <span className={path?.length !== index + 1 ? style.path_color : ''}>{item?.title}</span>
                                {path?.length !== index + 1 && <span className={style.rt} >{'>'}</span>}
                            </span>
                        })
                    }
                    {belongUser == '0' && publicPath?.map((item: { title: string }, index: number) => {
                        return <span key={index} onClick={() => { pathClick({ ...item, index }) }} >
                            <span className={publicPath?.length !== index + 1 ? style.path_color : ''}>{item?.title}</span>
                            {publicPath?.length !== index + 1 && <span className={style.rt} >{'>'}</span>}
                        </span>
                    })}
                </div>
                {/* 内容 */}
                <Spin spinning={list.loading} style={{ width: '100%' }}>
                    <div className={style.file_content} data-type="right-boxzones" id="file_content">
                        {listData?.records?.map((item: Item, index: number) => {
                            if (item.folder) {
                                {/* 文件夹模板 */ }
                                return <Popconfirm
                                    title="确定要删除吗？"
                                    onConfirm={() => { dels(item) }}
                                    okText="是"
                                    cancelText="否"
                                    onCancel={delPupOff}
                                    open={delPupId === item.id}
                                    key={item.id}
                                >
                                    <Spin tip='正在请求素材详情，请耐心等待...' spinning={get?.loading}>
                                        <div
                                            className={`${style.flex_box} ${selectFile?.some((id: number) => id === item.id) ? style.action : ''}`}
                                            onContextMenu={(e) => { rightMenu(e, item) }}
                                            onClick={(e) => {
                                                e.stopPropagation()
                                                e.preventDefault()
                                                changeClickFile(e, item, isAll, noFile)
                                            }}
                                            onDragStart={(e: any) => {
                                                e.preventDefault()
                                            }}
                                        >
                                            <img src={fileImg}
                                                className={style.flex_box_img}
                                                onClick={(e: any) => { e.stopPropagation(); fileClick(item) }}
                                                onDragOver={(ev) => {
                                                    ev.preventDefault()
                                                }}
                                                onDrop={() => {
                                                    if (item.id !== folderId) {
                                                        setActionId(item.id)
                                                    }
                                                }}
                                            />
                                            <span className={style.flex_box_name} >{item?.title}</span>
                                            <span className={style.flex_box_id} onClick={(e) => { copyId(e, item?.number) }} >{item?.number}</span>
                                        </div>
                                    </Spin>
                                </Popconfirm>
                            } else {
                                {/* 图片模板 ,视频模板,音频模板*/ }
                                let topPageElements: any
                                let topName: string = ""
                                if (mediaType === 'PAGE' && item?.pageSpecsList) {
                                    topPageElements = item?.pageSpecsList[0]?.pageElementsSpecList[0]
                                }
                                let El = null
                                if (mediaType === 'IMG') {
                                    El = <Image
                                        rootClassName={style.imgData}
                                        src={item.url}
                                        onClick={(e) => {
                                            e.stopPropagation()
                                            let className = (e.target as any).className
                                            if (className === 'ant-image-mask-info') {
                                                setShowImg(index)
                                            } else {
                                                changeClickFile(e, item, isAll, noFile)
                                            }
                                        }}
                                        preview={{
                                            visible: showImg === index,
                                            maskClassName: style.maskClass,
                                            onVisibleChange: (value) => {
                                                if (!value) {
                                                    setShowImg(-1)
                                                }
                                            }
                                        }}
                                    />
                                } else if (mediaType === 'VIDEO') {
                                    El = <VideoNews src={item.url} />
                                } else if (mediaType === 'PAGE') {
                                    switch (topPageElements?.elementType) {
                                        case 'TOP_IMAGE':
                                            topName = "顶部图片"
                                            El = <Image
                                                src={topPageElements?.topImageSpec?.imageUrl}
                                                preview={{ visible: false, maskClassName: style.maskClass }}
                                                onClick={(e) => {
                                                    e.stopPropagation()
                                                    let className = (e.target as any).className
                                                    if (className === 'ant-image-mask-info') {
                                                        setPage && setPage(1, item.id)
                                                    } else {
                                                        changeClickFile(e, item, isAll, noFile)
                                                    }
                                                }}
                                            />
                                            break
                                        case 'TOP_SLIDER':
                                            topName = "顶部轮播图"
                                            El = <>
                                                <Carousel autoplay style={{ width: 150, textAlign: 'center' }}>
                                                    {topPageElements?.topSliderSpec?.imageUrlList?.map((url: string, index: number) => <div key={index}>
                                                        <Image
                                                            preview={{ visible: false, maskClassName: style.maskClass }}
                                                            src={url}
                                                            onClick={(e) => {
                                                                e.stopPropagation()
                                                                let className = (e.target as any).className
                                                                if (className === 'ant-image-mask-info') {
                                                                    setPage && setPage(1, item.id)
                                                                } else {
                                                                    changeClickFile(e, item, isAll, noFile)
                                                                }
                                                            }} />
                                                    </div>)}
                                                </Carousel>
                                            </>
                                            break
                                        case 'TOP_VIDEO':
                                            topName = "顶部视频"
                                            El = <Image
                                                src={getVideoImgUrl(topPageElements?.topVideoSpec?.videoUrl)}
                                                preview={{ visible: false, maskClassName: style.maskClass }}
                                                onClick={(e) => {
                                                    e.stopPropagation()
                                                    let className = (e.target as any).className
                                                    if (className === 'ant-image-mask-info') {
                                                        setPage && setPage(1, item.id)
                                                    } else {
                                                        changeClickFile(e, item, isAll, noFile)
                                                    }
                                                }}
                                            />
                                            break
                                    }
                                }
                                return <Popconfirm
                                    title="确定要删除吗？"
                                    onConfirm={() => { dels(item.id) }}
                                    okText="是"
                                    cancelText="否"
                                    onCancel={delPupOff}
                                    open={delPupId === item.id}
                                    key={item.id}
                                >
                                    <Spin tip='正在请求素材详情，请耐心等待...' spinning={get?.loading} data-id={item.id}>
                                        <div
                                            className={`${style.image_box} ${!isBack ? (selectFile?.some((id: number) => id === item.id) ? style.action : '') : (selectItem?.some((item1: { url: string }) => item1.url === item.url) ? style.action : '')}`}
                                            onContextMenu={(e) => { rightMenu(e, item) }}
                                            onClick={(e) => { changeClickFile(e, item, isAll) }}
                                            {...moveConfig(item)}
                                        >
                                            <span className={`${style.select}`} onClick={(e) => { changeClickFile(e, item, isAll) }}>
                                                <span role="img" aria-label="check" style={{ color: '#fff' }}><svg viewBox="64 64 896 896" focusable="false" data-icon="check" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 00-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"></path></svg></span>
                                            </span>
                                            {El}
                                            <span className={style.flex_box_name} onClick={(e) => { copyId(e, item?.videoTitle || item?.title) }}>{item?.videoTitle || item?.title}</span>
                                            {mediaType === 'PAGE' ? <span>{topName}</span> : <span>{item?.width}*{item.height}</span>}
                                        </div>
                                    </Spin>
                                </Popconfirm>
                            }
                        })}
                    </div>
                </Spin>
                {/* 鼠标右键菜单 */}
                {rightClickPup.id ? rightClickPup.id === 'all' ? <Menu /> : <Menu isItem /> : null}
                {/* 新建文件弹窗 */}
                {fileVisible && <FileModal isAll={isAll} />}
                {/* 编辑排序 */}
                {sortVisible && <SortModal isAll={isAll} />}
                {/* 新建非图文 */}
                {imgVisrible && <ImgModal isAll={isAll} />}
                {imgsVisrible && <ImgsModal isAll={isAll} />}
                {/* 移动至 */}
                {moveShow && <MoveTo visible={moveShow} onClose={() => setMoveShow(false)} isAll={isAll} catalogueData={get_folder_tree.data} />}
            </div>
            <div className={style.pagination}>
                {/* 分页 */}
                {listData?.records?.length > 0 && <Pagination
                    showSizeChanger
                    onChange={(page: number, pageSize?: number) => {
                        getList({ pageSize, pageNum: page })
                    }}
                    onShowSizeChange={(current: number, size: number) => {
                        getList({ pageSize: size, pageNum: current })
                    }}
                    pageSizeOptions={['10', '20', '30', '50', '100']}
                    current={listData?.current}
                    defaultPageSize={30}
                    total={listData?.total}
                />}
            </div>
            <div className={style.moveSelected} id='moveSelected' />
        </div>

        {uploadVisible && <UploadsTable
            parentId={parentId}
            belongUser={belongUser}
            mediaType={mediaType}
            visible={uploadVisible}
            fileList={fileList}
            onClose={() => {
                setUploadVisible(false)
                setFileList(undefined)
            }}
            onChange={() => {
                setUploadVisible(false)
                setFileList(undefined)
                list.refresh()
            }}
        />}

        {/* 迁移素材 */}
        {migrateSc && <Migrate 
            visible={migrateSc}
            mediaType={mediaType as any}
            selectSc={selectItem}
            onClose={() => {
                setMigrateSc(false)
            }}
        />}
    </div>
}
export default React.memo(FlieBox)