import { Button, Card, Form, Input, message, Modal, Radio, Select, Space, TreeSelect, Upload } from "antd"
import React, { useEffect, useMemo, useState } from "react"
import '../../tencentAdPutIn/index.less'
import { useAjax } from "@/Hook/useAjax"
import { getUserAllApi } from "@/services/operating/account"
import { RcFile } from "antd/lib/upload"
import { UploadOutlined } from "@ant-design/icons"
import style from './index.less'
import CropperImg from "@/components/FileBoxAD/components/Cropper"
import { compressAccurately } from "image-conversion"
import { blobToBase64, dataURLtoFile, videoMessage } from "@/utils/compress"
import { getImgSize } from "@/utils/utils"
import request from "umi-request"
import { getFileUrl } from "@/services/launchAdq/material"
import getMD5 from "@/components/MD5"
import { addMaterialApi, getFolderListApi } from "@/services/adqV3/cloudNew"
import { DataNode } from "antd/lib/tree"
import { updateTreeData } from "./const"

interface Props {
    userId: number,
    folderId?: number
    visible?: boolean
    onChange?: () => void
    onClose?: () => void
}
/**
 * 上传素材
 * @returns 
 */
const UploadFile: React.FC<Props> = ({ visible, onClose, folderId, userId, onChange }) => {

    /**********************************/
    const [queryForm, setQueryForm] = useState<CLOUDNEW.AddMaterialProps>({ materialType: 'image' })
    const [fileList, setFileList] = useState<any>([])
    const [fileUrl, setFileUrl] = useState<string>('')
    const [previewVisible, setPreviewVisible] = useState<boolean>(false)
    const [visibleCropper, setVisibleCropper] = useState<boolean>(false)
    const [loading, setLoading] = useState<boolean>(false)
    const [treeData, setTreeData] = useState<DataNode[]>([]);

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

    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()
            })) || [])
        })
    }

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

    const handleOk = async () => {
        if (!folderId && !queryForm?.folderId) {
            message.error('当前不能上传素材，请选择文件夹')
            return
        }
        if (queryForm?.file) {
            let file = queryForm.file
            let fileSize = 0
            if (queryForm.materialType === 'image') {
                fileSize = 409600
            } else {
                fileSize = 524288000
            }

            if (queryForm.materialType === '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)
                    }
                    let newFile = await blobToBase64(bole)
                    message.warning({
                        content: `选择的图片大于${fileSize / 1024}KB，图片已压缩`,
                        duration: 3
                    })
                    file = await dataURLtoFile(newFile, file?.name)
                }
            } else if (queryForm.materialType === 'video') {
                if (file?.size > fileSize) { // 大于100mb进入压缩
                    message.error({
                        content: `选择的视频大于${fileSize / 1024 / 1024}MB，请重新选择提交`,
                        duration: 3
                    })
                    return
                }
            }
            setLoading(() => true)
            let width = 0
            let height = 0
            let videoDuration = 0
            if (queryForm.materialType === 'image') {
                const imgData = await getImgSize(file)
                width = imgData.width
                height = imgData.height
            } else if (queryForm.materialType === "video") {
                const videoInfo: { width: number, height: number, videoLength: number }[] = await videoMessage([file])
                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], queryForm?.materialName ? queryForm?.materialName + '.' + file?.name?.split('.')[1] : file?.name, { type: file?.type })
            const formData = new FormData();
            /**向阿里云请求上传地址*/
            getFileUrlAjx.run({ type: newFile.type, fileType: queryForm.materialType }).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) {
                            let fileMd5 = await getMD5(newFile)
                            let obj: CLOUDNEW.AddMaterialProps = { ...queryForm, 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 (queryForm.materialType === 'video') obj.videoDuration = videoDuration;
                            if (!obj?.materialName) obj.materialName = queryForm.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) => {
                                setLoading(() => false)
                                if (res) {
                                    message.success('添加成功')
                                    onChange?.()
                                }
                            }).catch(() => setLoading(() => false))
                        }
                    } else {
                        message.error('上传失败！')
                    }
                }).catch(() => setLoading(() => false))
            }).catch(() => setLoading(() => false))
        } else {
            message.error('请选择素材')
        }
    }

    const getVideo = useMemo(() => {
        if (queryForm?.materialType === 'video') {
            if (queryForm?.file) {
                return <video src={URL.createObjectURL(queryForm?.file)} style={{ width: 200 }} controls />
            } else {
                return null
            }
        } else {
            return null
        }
    }, [queryForm?.file])

    // 下级目录
    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()
                })) || []),
            );
        })
    }

    return <Modal
        title={<strong>{'上传素材'}</strong>}
        open={visible}
        onCancel={onClose}
        onOk={handleOk}
        className="modalResetCss"
        bodyStyle={{ backgroundColor: '#f1f4fc', maxHeight: 650, overflow: 'hidden', overflowY: 'auto', padding: '10px' }}
        maskClosable={false}
        width={600}
        confirmLoading={loading}
    >
        <Card className="cardResetCss">
            <Form
                labelAlign='left'
                labelCol={{ span: 4 }}
                layout="horizontal"
                colon={false}
                style={{}}
            >
                <Form.Item label={<strong>素材名称</strong>}>
                    <Input placeholder="素材名称(不填是上传素材名称)" value={queryForm?.materialName} onChange={(e) => setQueryForm({ ...queryForm, materialName: e.target.value })} />
                </Form.Item>

                <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>

                <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>

                <Form.Item label={<strong>素材类型</strong>}>
                    <Radio.Group value={queryForm?.materialType} onChange={(e) => setQueryForm({ ...queryForm, materialType: e.target.value })} buttonStyle="solid">
                        <Radio.Button value="image">图片</Radio.Button>
                        <Radio.Button value="video">视频</Radio.Button>
                    </Radio.Group>
                </Form.Item>

                <Form.Item label={<strong>描述</strong>}>
                    <Input.TextArea placeholder="描述" value={queryForm?.description} onChange={(e) => setQueryForm({ ...queryForm, description: e.target.value })} />
                </Form.Item>

                <Form.Item label={<strong>{queryForm?.materialType ? '上传图片' : '上传视频'}</strong>}>
                    {queryForm?.materialType === 'image' ? <Space>
                        <Upload
                            listType="picture-card"
                            accept='image/gif,image/jpeg,image/png,image/jpg'
                            beforeUpload={(file: RcFile) => {
                                return false
                            }}
                            fileList={fileList}
                            onChange={(newFileList: any) => {
                                console.log('newFileList-->', newFileList)
                                setQueryForm({ ...queryForm, file: newFileList.file })
                                setFileList([...newFileList.fileList])
                            }}
                            onPreview={(file: any) => {
                                setPreviewVisible(true)
                                setFileUrl(file.thumbUrl)
                            }}
                            onRemove={() => {
                                setQueryForm({ ...queryForm, file: null })
                            }}
                        >
                            {fileList?.length < 1 && '普通上传'}
                        </Upload>
                        {fileList?.length === 0 && <Upload
                            listType="picture-card"
                            accept='image/gif,image/jpeg,image/png,image/jpg'
                            beforeUpload={(file: RcFile) => {
                                return false
                            }}
                            fileList={fileList}
                            onChange={(newFileList: any) => {
                                setQueryForm({ ...queryForm, file: newFileList.file })
                                setVisibleCropper(true)
                            }}
                            onRemove={() => {
                                setQueryForm({ ...queryForm, file: null })
                            }}
                            onPreview={(file: any) => {
                                setPreviewVisible(true)
                                setFileUrl(file.thumbUrl)
                            }}
                        >
                            {fileList?.length < 1 && '裁剪上传'}
                        </Upload>}
                    </Space> : <>
                        <div className={style.file}>
                            <Button type='primary'><UploadOutlined />上传视频</Button>
                            <input type='file' onChange={(e) => {
                                if (e?.target?.files) {
                                    setQueryForm({ ...queryForm, file: e?.target?.files[0] })
                                }
                            }} accept="video/*" />
                        </div>
                        {queryForm?.file && <>
                            <p>{queryForm?.file?.name}</p>
                            {getVideo}
                        </>}
                    </>}

                </Form.Item>
            </Form>
        </Card>

        {/* 预览 */}
        <Modal
            open={previewVisible}
            footer={null}
            onCancel={() => {
                setPreviewVisible(false)
            }}
        >
            <img alt="example" style={{ width: '100%' }} src={fileUrl} />
        </Modal>

        {/* 裁剪 */}
        {visibleCropper && <CropperImg visible={visible} onClose={() => setVisibleCropper(false)} file={queryForm.file} onChange={(fileList: any[], file: any) => { setFileList(fileList); setQueryForm({ ...queryForm, file: file }); setVisibleCropper(false) }} />}
    </Modal>
}

export default React.memo(UploadFile)