import { Button, List, Space, Typography } from "antd"
import React, { useEffect, useState } from "react"
import { MediaContentProps, MediaTypeProps } from "../../API/weMaterial/weMaterial";
import style from './index.less'
import ContentBox from "./contentBox";
import TextModal from "./textModal";
import UploadButton, { MediaSize } from "./uploadButton";
import { formatSize, getAudioTime } from "@/utils/utils";
import { RcFile } from "antd/es/upload";
import LinkModal from "./linkModal";
import MiniprogramModal from "./miniprogramModal";
import { arrayMove } from "react-sortable-hoc";
import { useUpdateEffect } from "ahooks";
import MaterialLibraryMould from "../materialLibraryMould";
import { getImgSize, videoMessage } from "@/utils/compress";

interface Props {
    posiType?: 'PYQ' | 'QF'
    value?: any
    onChange?: (value?: any) => void,
    boxHeight?: number,//内容高度限制,
    dataNum?: number,//限制数量
    noShowType?: Array<'text' | 'video' | 'file' | 'link' | 'voice' | 'miniprogram' | 'sck' | 'image'>,//不可使用的素材
    friendsImgs?: boolean,//是否执行朋友圈图片规则
    type?: 'text' | 'video' | 'file' | 'link' | 'voice' | 'miniprogram' | 'image',//只能选择的素材
    textCount?: number,  // 可选文案数量
    mediaSize?: MediaSize
    disabledAdd?: boolean
}
/**
 * 内容组件
 * @returns 
 */
const MaterialMould: React.FC<Props> = ({ value, onChange, boxHeight, dataNum, noShowType, type = undefined, mediaSize, posiType, textCount, disabledAdd }) => {
    const [dataLength, setDataLength] = useState(dataNum || 9)
    /*******************************/
    const [openText, setOpenText] = useState(false)
    const [openLink, setOpenLink] = useState(false)
    const [openMiniprogram, setOpenMiniprogram] = useState(false)
    const [openMateria, setOpenMateria] = useState(false)
    const [isInsert, setIsInsert] = useState<boolean>(false)  // 是否插入

    const [subscript, setSubscript] = useState<number>(0)
    const [data, setData] = useState<MediaContentProps[]>([])
    /*******************************/

    useEffect(() => {
        if (value) {
            setData(value)
        }
    }, [value])

    useEffect(() => {
        if (dataNum) {
            setDataLength(dataNum)
        }
    }, [dataNum])

    return <div>
        <List
            header={null}
            footer={<Space wrap>
                <Typography.Text>{data.length}/{dataLength}</Typography.Text>
                {!(noShowType?.some(i => i === 'text')) && !textCount && <Button disabled={data.length === dataLength || disabledAdd} onClick={() => { setOpenText(true); setSubscript(data.length); setIsInsert(false) }}>文字</Button>}
                {!(noShowType?.some(i => i === 'image')) && < UploadButton text="图片" mediaSize={mediaSize} disabled={data.length === dataLength || disabledAdd} type='image' onChange={async (url, file) => {
                    let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                    let imgData = await getImgSize(file as RcFile)
                    NewData[data.length] = {
                        mediaType: 'image',
                        imageUrl: url,
                        mediaFormat: file?.name?.split('.')[1],
                        mediaSize: file?.size?.toString(),
                        mediaWidth: imgData.width.toString(),
                        mediaHeight: imgData.height.toString()
                    }
                    setData(NewData)
                    onChange?.(NewData)
                }} />}
                {!(noShowType?.some(i => i === 'video')) && <UploadButton text="视频" mediaSize={mediaSize} disabled={data.length === dataLength || disabledAdd} type='video' tooltip="发送视频传送比较耗时，如果发送消息间隔设置又较短，可能会出现消息乱序，所以视频尽量压缩小一点" onChange={async (url, file) => {
                    let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                    let videoInfo: any = await videoMessage([file as RcFile])
                    NewData[data.length] = {
                        mediaType: 'video',
                        videoUrl: url,
                        mediaFormat: file?.name?.split('.')[1],
                        mediaSize: file?.size?.toString(),
                        mediaWidth: videoInfo[0]?.width?.toString(),
                        mediaHeight: videoInfo[0]?.height?.toString(),
                        mediaPlayTime: videoInfo[0]?.videoLength?.toString()
                    }
                    setData(NewData)
                    onChange?.(NewData)
                }} />}
                {!(noShowType?.some(i => i === 'file')) && <UploadButton mediaSize={mediaSize} text="文件" disabled={data.length === dataLength || disabledAdd} type='file' onChange={(url, file, name) => {
                    let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                    NewData[data.length] = {
                        mediaType: 'file',
                        fileUrl: url,
                        fileName: name || file?.name,
                        mediaSize: file?.size?.toString(),  //formatSize(file?.size)
                        mediaFormat: file?.name?.split('.')[1],
                    }
                    setData(NewData)
                    onChange?.(NewData)
                }} />}
                {!(noShowType?.some(i => i === 'link')) && <Button disabled={data.length === dataLength || disabledAdd} onClick={() => { setOpenLink(true); setSubscript(data.length); setIsInsert(false) }}>链接</Button>}
                {/* {!(noShowType?.some(i => i === 'voice')) && <UploadButton mediaSize={mediaSize} text="语音" disabled={data.length === dataLength} type='voice' onChange={async (url, file) => {
                    let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                    let times = await getAudioTime(file as RcFile)
                    NewData[data.length] = {
                        mediaType: 'voice',
                        voiceUrl: url,
                        mediaPlayTime: times as string,
                        mediaSize: file?.size?.toString(),  //formatSize(file?.size)
                        mediaFormat: file?.name?.split('.')[1],
                    }
                    setData(NewData)
                    onChange?.(NewData)
                }} />} */}
                {!(noShowType?.some(i => i === 'miniprogram')) && <Button disabled={data.length === dataLength || disabledAdd} onClick={() => { setOpenMiniprogram(true); setSubscript(data.length); setIsInsert(false) }}>小程序</Button>}
                {!(noShowType?.some(i => i === 'sck')) && <Button disabled={data.length === dataLength || disabledAdd} onClick={() => { setOpenMateria(true); setSubscript(data.length); setIsInsert(false) }}>素材库</Button>}
            </Space>}
            bordered
            dataSource={['']}
            renderItem={(item) => (
                data?.length > 0 ? <List.Item className={style.material}>
                    <div style={boxHeight ? { height: boxHeight, overflowY: 'auto' } : {}}>
                        <ContentBox
                            mediaSize={mediaSize}
                            noShowType={noShowType}
                            data={data}
                            dataLength={dataLength}
                            textCount={textCount}
                            disabledAdd={disabledAdd}
                            onChange={async (item, index, type, mediaType, file, name) => {
                                switch (type) {
                                    case 'add':
                                        setIsInsert(true)
                                        if (mediaType && ['image', 'video', 'file', 'vioce'].includes(mediaType)) {
                                            let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                                            let cont: any = {}
                                            cont = { mediaType: mediaType as MediaTypeProps }
                                            cont[`${mediaType}Url`] = item as string
                                            cont['mediaSize'] = file?.size
                                            cont['mediaFormat'] = file?.name?.split('.')[1]
                                            if (mediaType === 'file') {
                                                cont['fileName'] = name || file?.name
                                            }
                                            if (mediaType === 'voice') {
                                                let times = await getAudioTime(file as RcFile)
                                                cont['mediaPlayTime'] = times as string
                                            }
                                            if (mediaType === 'image') {
                                                let imgData = await getImgSize(file as RcFile)
                                                cont['mediaWidth'] = imgData.width.toString()
                                                cont['mediaHeight'] = imgData.height.toString()
                                            }
                                            if (mediaType === 'video') {
                                                let videoInfo: any = await videoMessage([file as RcFile])
                                                cont['mediaWidth'] = videoInfo[0]?.width?.toString()
                                                cont['mediaHeight'] = videoInfo[0]?.height?.toString()
                                                cont['mediaPlayTime'] = videoInfo[0]?.videoLength?.toString()
                                            }
                                            NewData.splice(index + 1, 0, cont)
                                            setData(NewData)
                                            onChange?.(NewData)
                                        } else if (mediaType === 'text') {
                                            setSubscript(index)
                                            setOpenText(true);
                                        } else if (mediaType === 'link') {
                                            setSubscript(index)
                                            setOpenLink(true);
                                        } else if (mediaType === 'miniprogram') {
                                            setSubscript(index)
                                            setOpenMiniprogram(true)
                                        } else if (mediaType === 'sck') {
                                            setSubscript(index)
                                            setOpenMateria(true)
                                        }
                                        break
                                    case 'edit':
                                        setIsInsert(false)
                                        if (mediaType && ['image', 'video', 'file', 'voice'].includes(mediaType)) {
                                            let NewData: any[] = JSON.parse(JSON.stringify(data))
                                            let id = NewData[index]?.id
                                            NewData[index] = { mediaType: mediaType as MediaTypeProps }
                                            NewData[index][`${mediaType}Url`] = item as string
                                            NewData[index]['mediaSize'] = file?.size?.toString()
                                            NewData[index]['mediaFormat'] = file?.name?.split('.')[1]
                                            if (mediaType === 'file') {
                                                NewData[index]['fileName'] = file?.name
                                            }
                                            if (mediaType === 'voice') {
                                                let times = await getAudioTime(file as RcFile)
                                                NewData[index]['mediaPlayTime'] = times as string
                                            }
                                            if (mediaType === 'image') {
                                                let imgData = await getImgSize(file as RcFile)
                                                NewData[index]['mediaWidth'] = imgData.width.toString()
                                                NewData[index]['mediaHeight'] = imgData.height.toString()
                                            }
                                            if (mediaType === 'video') {
                                                let videoInfo: any = await videoMessage([file as RcFile])
                                                NewData[index]['mediaWidth'] = videoInfo[0]?.width?.toString()
                                                NewData[index]['mediaHeight'] = videoInfo[0]?.height?.toString()
                                                NewData[index]['mediaPlayTime'] = videoInfo[0]?.videoLength?.toString()
                                            }
                                            if (id) {
                                                NewData[index].id = id
                                            }
                                            setData(NewData)
                                            onChange?.(NewData)
                                        } else if (mediaType === 'text') {
                                            setSubscript(index)
                                            setOpenText(true);
                                        } else if (mediaType === 'link') {
                                            setSubscript(index)
                                            setOpenLink(true);
                                        } else if (mediaType === 'miniprogram') {
                                            setSubscript(index)
                                            setOpenMiniprogram(true)
                                        }
                                        break
                                    case 'del':
                                        const newDelData = data.filter((item, index1) => index !== index1)
                                        setData(newDelData)
                                        onChange?.(newDelData)
                                        break
                                    case 'down':
                                        const newDownData = arrayMove(data, index, index + 1)
                                        setData(newDownData)
                                        onChange?.(newDownData)
                                        break
                                    case 'downV':
                                        const newDownVData = arrayMove(data, index, data.length)
                                        setData(newDownVData)
                                        onChange?.(newDownVData)
                                        break
                                    case 'up':
                                        const newUpData = arrayMove(data, index, index - 1)
                                        setData(newUpData)
                                        onChange?.(newUpData)
                                        break;
                                    case 'upV':
                                        const newUpVData = arrayMove(data, index, 0)
                                        setData(newUpVData)
                                        onChange?.(newUpVData)
                                        break
                                }
                            }}
                        />
                    </div>
                </List.Item> : null
            )}
        />


        {/* 文字信息弹窗 */}
        {openText && <TextModal
            visible={openText}
            onChange={(text) => {
                let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                if (isInsert) { // 插入
                    let cont: any = {
                        mediaType: 'text',
                        textContent: text
                    }
                    NewData.splice(subscript + 1, 0, cont)
                } else {
                    let id = NewData[subscript]?.id
                    NewData[subscript] = {
                        mediaType: 'text',
                        textContent: text
                    }
                    if (id) {
                        NewData[subscript].id = id
                    }
                }
                setData(NewData)
                onChange?.(NewData)
                setOpenText(false)
            }}
            onClose={() => setOpenText(false)}
            value={isInsert ? undefined : data?.[subscript]?.textContent}
        />}
        {/* 链接信息弹窗 */}
        {openLink && <LinkModal
            type={posiType}
            visible={openLink}
            onClose={() => setOpenLink(false)}
            value={isInsert ? undefined : data?.[subscript]}
            onChange={(value) => {
                let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                if (isInsert) { // 插入
                    let cont: any = {
                        mediaType: 'link',
                        ...value
                    }
                    NewData.splice(subscript + 1, 0, cont)
                } else {
                    let id = NewData[subscript]?.id
                    NewData[subscript] = {
                        mediaType: 'link',
                        ...value
                    }
                    if (id) {
                        NewData[subscript].id = id
                    }
                }
                setData(NewData)
                onChange?.(NewData)
                setOpenLink(false)
            }}
        />}
        {/* 小程序信息弹窗 */}
        {openMiniprogram && <MiniprogramModal
            visible={openMiniprogram}
            value={isInsert ? undefined : data?.[subscript]}
            onClose={() => setOpenMiniprogram(false)}
            onChange={(value) => {
                let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                if (isInsert) { // 插入
                    let cont: any = {
                        mediaType: 'miniprogram',
                        ...value
                    }
                    NewData.splice(subscript + 1, 0, cont)
                } else {
                    let id = NewData[subscript]?.id
                    NewData[subscript] = {
                        mediaType: 'miniprogram',
                        ...value
                    }
                    if (id) {
                        NewData[subscript].id = id
                    }
                }
                setData(NewData)
                onChange?.(NewData)
                setOpenMiniprogram(false)
            }}
        />}
        {/* 素材库导入 */}
        {openMateria && <MaterialLibraryMould
            scLength={data.length}
            visible={openMateria}
            onClose={() => setOpenMateria(false)}
            type={type}
            noShowType={noShowType}
            mediaSize={mediaSize}
            textCount={textCount}
            dataLength={dataLength}
            onChange={value => {
                if (value && Array.isArray(value)) {
                    let NewData: MediaContentProps[] = JSON.parse(JSON.stringify(data))
                    if (isInsert) { // 插入
                        value.unshift((subscript + 1) as any, 0 as any)
                        Array.prototype.splice.apply(NewData, value as any);
                        setData(NewData)
                        onChange?.(NewData)
                    } else {
                        setData([...NewData, ...value])
                        onChange?.([...NewData, ...value])
                    }
                }
            }}
        />}
    </div>
}


export default React.memo(MaterialMould)