import { Badge, Button, Card, Col, Form, message, Modal, Row, Select, Space, Table, TreeSelect } from "antd"
import React, { useEffect, useRef, useState } from "react"
import { compressAccurately } from "image-conversion"
import { blobToBase64, dataURLtoFile, videoMessage } from "@/utils/compress"
import { getImgSize } from "@/utils/utils"
import { useAjax } from "@/Hook/useAjax"
import { bdSysMediaAdd, getFileUrl } from "@/services/launchAdq/material"
import request from "umi-request"
import getMD5 from "@/components/MD5"
import { addMaterialApi, getFolderListApi } from "@/services/adqV3/cloudNew"
import '../../tencentAdPutIn/index.less'
import { getUserAllApi } from "@/services/operating/account"
import { DataNode } from "antd/lib/tree"
import { updateTreeData } from "./const"

interface Props {
    isPermission: boolean,
    userId: number,
    folderId?: any
    fileList?: FileList
    visible?: boolean
    onClose?: () => void
    onChange?: () => void
}
const UploadsTable: React.FC<Props> = ({ isPermission, fileList, visible, onClose, onChange, folderId, userId }) => {

    /*******************************/
    const [queryForm, setQueryForm] = useState<CLOUDNEW.AddMaterialProps>({})
    const [dataSource, setDataSource] = useState<any[]>([])
    const [loading, setLoading] = useState<boolean>(false)
    const tableRef = useRef(null);
    const [treeData, setTreeData] = useState<DataNode[]>([]);

    //请求上传地址
    const getFileUrlAjx = useAjax((params: { type: string, fileType: 'video' | 'image' }) => getFileUrl(params), { manual: true })
    const addMaterial = useAjax((params) => addMaterialApi(params))
    const getUserAll = useAjax(() => getUserAllApi())
    const getFolderList = useAjax((params) => getFolderListApi(params))
    /*******************************/

    useEffect(() => {
        getUserAll.run()
    }, [])

    useEffect(() => {
        getFolder()
    }, [])

    const getFolder = () => {
        getFolderList.run({}).then(res => {
            setTreeData(() => res?.map((item: { folderName: any; id: any; createBy: number }) => ({
                title: item.folderName,
                value: item.id,
                key: item.id,
                disabled: userId.toString() !== item.createBy.toString()
            })) || [])
        })
    }

    // 下级目录
    const handleUpdateFolder = (parentId: number) => {
        return getFolderListApi({ parentId }).then(res => {
            setTreeData(origin =>
                updateTreeData(origin, parentId, res?.data?.map((item: { folderName: any; id: any; createBy: number }) => ({
                    title: item.folderName,
                    value: item.id,
                    key: item.id,
                    disabled: userId.toString() !== item.createBy.toString()
                })) || []),
            );
        })
    }

    const scrollToRow = (key: number) => {
        if (tableRef.current) {
            const tableBody = (tableRef.current as any).querySelector('.ant-table-body');
            const row = tableBody.querySelector(`.ant-table-row[data-row-key="${key}"]`);

            if (row) {
                row.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
        }
    };

    useEffect(() => {
        if (fileList?.length) {
            setDataSource([...Array.from(fileList)].map((file, index) => {
                let type = 'default'
                let mediaTypeName = '其它文件'
                if (file.type.startsWith('image/')) {
                    mediaTypeName = '图片'
                } else if (file.type.startsWith('video/')) {
                    mediaTypeName = '视频'
                } else {
                    type = 'warning'
                }
                return { id: index + 1, file, type, mediaTypeName }
            }))
        } else {
            setDataSource([])
        }
    }, [fileList])

    // 上传方法
    const upload = (file: File) => {
        return new Promise(async (resolve) => {
            let fileSize = 0
            if (file.type.startsWith('image/')) {
                fileSize = 409600
            } else {
                fileSize = 524288000
            }

            if (file.type.startsWith('image/')) {
                if (file?.size > fileSize) { // 大于400kb进入压缩
                    let bole = await compressAccurately(file, fileSize / 1024 - 50)
                    if (bole?.size > fileSize) {
                        bole = await compressAccurately(file, fileSize / 1024 - 100)
                    }
                    if (bole?.size > fileSize) {
                        bole = await compressAccurately(file, fileSize / 1024 - 150)
                    }
                    if (bole?.size > fileSize) {
                        bole = await compressAccurately(file, fileSize / 1024 - 200)
                    }
                    const newFile = await blobToBase64(bole)
                    file = await dataURLtoFile(newFile, file?.name)
                }
            } else if (file.type.startsWith('video/')) {
                if (file?.size > fileSize) { // 大于500mb
                    return resolve(`选择的视频大于${fileSize / 1024 / 1024}MB，请重新选择提交`)
                }
            }
            setLoading(() => true)
            let width = 0
            let height = 0
            let videoDuration = 0
            if (file.type.startsWith('image/')) {
                const imgData = await getImgSize(file as any)
                width = imgData.width
                height = imgData.height
            } else if (file.type.startsWith('video/')) {
                const videoInfo: { width: number, height: number, videoLength: number }[] = await videoMessage([file as any])
                try {
                    const readChunk = async (chunkSize: number, offset: number) => new Uint8Array(await file.slice(offset, offset + chunkSize).arrayBuffer());
                    // @ts-ignore
                    const mediaInfo = await MediaInfo.mediaInfoFactory({ format: 'object' })
                    const result = await mediaInfo.analyzeData(file.size, readChunk)
                    if (result?.media?.track) {
                        const { Height, Width, Duration } = result?.media?.track.find((item: { [x: string]: string }) => item['@type'] === 'Video')
                        width = Width
                        height = Height
                        videoDuration = Duration
                    } else {
                        width = videoInfo[0].width
                        height = videoInfo[0].height
                        videoDuration = videoInfo[0].videoLength
                    }
                } catch (error) {
                    width = videoInfo[0].width
                    height = videoInfo[0].height
                    videoDuration = videoInfo[0].videoLength
                }
            }
            /**修改文件名以用户设置的文件title命名*/
            const newFile = new File([file], file?.name, { type: file?.type })
            const formData = new FormData();
            /**向阿里云请求上传地址*/
            getFileUrlAjx.run({ type: newFile.type, fileType: file.type.startsWith('video/') ? 'video' : 'image' }).then(res1 => {
                Object.keys(res1).forEach((key: string) => {
                    if (key !== 'url') {
                        formData.append(key, res1[key])
                    }
                })
                formData.append('file', newFile)
                /**向阿里云返回的上传地址上传文件*/
                request(res1?.ossUrl, { method: 'post', body: formData }).then(async (res2: { code: number, data: { url: string } }) => {
                    if (res2.code === 200) {
                        /**取到返回的文件地址向后端发送具体数据*/
                        if (res2?.data?.url) {
                            const fileMd5 = await getMD5(newFile)
                            const obj: CLOUDNEW.AddMaterialProps = { ...queryForm, materialType: file.type.startsWith('video/') ? 'video' : 'image', width, height, md5: fileMd5, ossUrl: res2?.data?.url, fileSize: newFile?.size, fileMime: newFile.type, aspectRatio: width / height }
                            delete obj?.file
                            if (!obj?.folderId) obj.folderId = folderId
                            if (!obj?.designerId) obj.designerId = userId;
                            if (file.type.startsWith('video/')) obj.videoDuration = videoDuration;
                            if (!obj?.materialName) obj.materialName = file.name;
                            if (obj?.materialName && obj.materialName.match(RegExp(/[<>&\\'"/\x08\x09\x0A\x0D\x7F]/g))) {
                                obj.materialName = obj.materialName.replace(RegExp(/[<>&\\'"/\x08\x09\x0A\x0D\x7F]/g), '')
                            }
                            obj.materialName = (obj as any).materialName.replace(/\.(jpg|jpeg|gif|png|mp4)$/i, '')
                            addMaterial.run(obj).then((res) => {
                                if (res) {
                                    resolve('')
                                }
                                resolve(`上传失败`)
                            }).catch(() => resolve(`上传失败`))
                        }
                    } else {
                        resolve(`上传失败`)
                    }
                }).catch(() => resolve(`上传失败`))
            }).catch(() => resolve(`上传失败`))
        })
    }

    // 点击上传
    const handleOk = () => {
        if (!folderId && !queryForm?.folderId) {
            message.error('当前不能上传素材，请选择文件夹')
            return
        }
        if (!isPermission) {
            message.error('当前文件夹没有操作权限，请选择文件夹')
            return
        }
        setLoading(true)
        async function uoload(index: number) {
            let fileData = dataSource[index]
            scrollToRow(index)
            if (fileData?.type === 'default') {
                setDataSource(data => {
                    const newData = [...data]
                    newData[index].type = 'processing'
                    return newData
                })
                let error = await upload(fileData.file)
                setDataSource(data => {
                    const newData = [...data]
                    newData[index].type = error ? 'error' : 'success'
                    newData[index].error = error
                    return newData
                })
            }
            if (dataSource.length > index) {
                uoload(index + 1)
            } else { // 上传完成
                setLoading(false)
                onChange?.()
            }
        }
        uoload(0)
    }

    return <Modal
        title={<strong>上传素材预览</strong>}
        open={visible}
        className='modalResetCss'
        width={1100}
        closable={false}
        maskClosable={false}
        bodyStyle={{ backgroundColor: '#f1f4fc', maxHeight: 650, overflow: 'hidden', overflowY: 'auto', padding: '10px' }}
        footer={<Space>
            {!loading && <Button onClick={onClose}>取消</Button>}
            <Button type="primary" onClick={handleOk} loading={loading}>上传</Button>
        </Space>}
    >
        <Space direction="vertical" style={{ width: '100%' }}>
            <Card className="cardResetCss">
                <Form
                    labelAlign='left'
                    labelCol={{ span: 4 }}
                    layout="horizontal"
                    colon={false}
                    style={{}}
                >
                    <Row gutter={20}>
                        <Col span={12}>
                            <Form.Item label={<strong>设计师</strong>}>
                                <Select
                                    placeholder="请选择设计师(不选默认自己)"
                                    filterOption={(input, option) =>
                                        ((option?.label ?? '') as any).toLowerCase().includes(input.toLowerCase())
                                    }
                                    value={queryForm?.designerId}
                                    onChange={(e => setQueryForm({ ...queryForm, designerId: e }))}
                                    options={getUserAll?.data?.map((item: { nickname: any; userId: any }) => ({ label: item.nickname, value: item.userId }))}
                                />
                            </Form.Item>
                        </Col>
                        <Col span={12}>
                            <Form.Item label={<strong>文件夹</strong>}>
                                <TreeSelect
                                    loading={getFolderList.loading}
                                    allowClear
                                    style={{ width: '100%' }}
                                    value={queryForm?.folderId}
                                    dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                                    placeholder="请选择文件夹(不选择默认当前文件夹)"
                                    onChange={(e) => {
                                        setQueryForm({ ...queryForm, folderId: e })
                                    }}
                                    loadData={({ value }) => {
                                        return new Promise<void>(async (resolve) => {
                                            await handleUpdateFolder(Number(value))
                                            resolve()
                                        })
                                    }}
                                    treeData={treeData}
                                />
                            </Form.Item>
                        </Col>
                    </Row>
                </Form>
            </Card>
            <Card className="cardResetCss">
                <Table
                    dataSource={dataSource}
                    size="small"
                    rowKey={'id'}
                    bordered
                    ref={tableRef}
                    scroll={{ y: 450 }}
                    pagination={{
                        defaultPageSize: 100
                    }}
                    columns={[
                        {
                            title: '序号',
                            dataIndex: 'id',
                            key: 'id',
                            width: 60,
                            align: 'center',
                            fixed: 'left',
                            render: text => <span style={{ fontSize: 12 }}>{text}</span>
                        },
                        {
                            title: '上传状态',
                            dataIndex: 'type',
                            key: 'type',
                            width: 130,
                            fixed: 'left',
                            render(value) {
                                switch (value) {
                                    case 'success':
                                        return <Badge status="success" text={<span style={{ fontSize: 12 }}>上传成功</span>} />
                                    case 'processing':
                                        return <Badge status="processing" text={<span style={{ fontSize: 12 }}>正在上传...</span>} />
                                    case 'error':
                                        return <Badge status="error" text={<span style={{ fontSize: 12 }}>上传失败</span>} />
                                    case 'error_qx':
                                        return <Badge status="error" text={<span style={{ fontSize: 12 }}>取消上传</span>} />
                                    case 'warning':
                                        return <Badge status="warning" text={<span style={{ fontSize: 12 }}>{`当前只能上传图片和视频`}</span>} />
                                    default:
                                        return <Badge status="default" text={<span style={{ fontSize: 12 }}>等待上传</span>} />
                                }
                            },
                        },
                        {
                            title: '素材类型',
                            dataIndex: 'mediaTypeName',
                            key: 'mediaTypeName',
                            width: 75,
                            align: 'center',
                            render: text => <span style={{ fontSize: 12 }}>{text}</span>
                        },
                        {
                            title: '素材名称',
                            dataIndex: 'file',
                            key: 'file',
                            width: 150,
                            render(value, record) {
                                if (record.mediaTypeName === '图片' || record.mediaTypeName === '视频') {
                                    return <span style={{ fontSize: 12 }}>{value?.name}</span>
                                }
                                return <span style={{ fontSize: 12 }}>其它文件</span>
                            },
                        },
                        {
                            title: '素材',
                            dataIndex: 'file',
                            key: 'file',
                            width: 230,
                            render(value, record) {
                                if (record.mediaTypeName === '图片') {
                                    return <img src={URL.createObjectURL(value)} style={{ height: 100, maxWidth: 200 }} />
                                } else if (record.mediaTypeName === '视频') {
                                    return <video src={URL.createObjectURL(value)} style={{ maxWidth: 200, height: 100 }}></video>
                                }
                                return <span style={{ fontSize: 12 }}>其它文件</span>
                            },
                        },
                        {
                            title: '错误信息',
                            dataIndex: 'error',
                            key: 'error',
                            width: 300,
                            render: text => <span style={{ fontSize: 12 }}>{text || '--'}</span>
                        },
                        {
                            title: '操作',
                            dataIndex: 'cz',
                            key: 'cz',
                            width: 70,
                            align: 'center',
                            fixed: 'right',
                            render(_, record) {
                                if (record.type === 'default') {
                                    return <a
                                        style={{ fontSize: 12, color: 'red' }}
                                        onClick={() => {
                                            setDataSource(data => {
                                                return data.map(item => item.id === record.id ? { ...item, type: 'error_qx' } : item)
                                            })
                                        }}
                                    >取消上传</a>
                                }
                                return '--'
                            },
                        },
                    ]}
                />
            </Card>
        </Space>
    </Modal>
}

export default React.memo(UploadsTable)