import { useModel } from 'umi'
import { Modal, Button, Form, Select, message, Space, Image as AntImg, Row, Col, Upload, Input } from 'antd'
import { SelectValue } from 'antd/es/select'
import Cropprt from '@/components/Cropper'
import React, { useCallback, useEffect, useState } from "react"
const { Option } = Select
import style from './index.less'
import { request } from 'umi'
import { api } from '@/services/api'
import { DeleteOutlined, InboxOutlined } from '@ant-design/icons'
import { RcFile } from 'antd/lib/upload'
const { Dragger } = Upload
const { TextArea } = Input
import getMD5 from '@/components/MD5'

type Props = {
    visible: boolean,
    // handleOk: () => void
    hideModal: () => void,
    editData?: any,
    ajax: any,
    dataType: string
}
const channelCon = ['朋友圈信息流','公众平台流量','广点通','小程序','头条','抖音']
function AddOriginality(props: Props) {
    let { visible, hideModal, editData, ajax, dataType: typeData } = props
    const [loading, setLoading] = useState<boolean>(false)
    const [imgs, setImgs] = useState<string[]>([])
    const [video, setVideo] = useState<RcFile>()
    const [imgLength, setImgLength] = useState<{width: number, height: number}>({width: 800, height: 800})
    const [fileList, setFileList] = useState<any[]>([])
    const [queryForm, setQueryForm] = useState<any>({media: '', title: '', article: '', labels: [], type: 1, channel: undefined, dataType: '', id: undefined})
    const { addIdeas, getLabels, editIdeas } = useModel('useLaunch.useMaterial')
    useEffect(()=>{
        if(editData && typeof editData === 'object' && Object.keys(editData).length > 0) {
            let {media, labels, type, channel, id, title, article, dataType} = editData
            setImgs(media?.split(','))
            setQueryForm({media,labels: labels?.split(',') || [], type, id, channel, title, article, dataType})
        }else {
            setQueryForm({media: '', labels: [], type: 1, channel: undefined, id: undefined, title: '', article: '', dataType: ''})
        }
    }, [editData])
    useEffect(() => {
        getLabels.run({pageNum: 1, pageSize: 200})
    }, [])

    /** 选择了图片触发 */
    const setImgsHandle = useCallback(async (img: any) => {
        if (img) {
            if (imgs.length > 0) {
                let file = await dataURLtoFile(img, Math.round(new Date() as any / 1000))
                let md5 = await getMD5(file)
                for (let item of imgs) {
                    let file = await dataURLtoFile(item, Math.round(new Date() as any / 1000))
                    let md5s = await getMD5(file)
                    if (md5 === md5s) {
                        message.error('请选择不同图片!')
                        return
                    }
                }
                let onesCk = await imgMessage([imgs[0]])
                let imgCK = await imgMessage([img])
                if ((onesCk[0]?.width !== imgCK[0]?.width) || (onesCk[0]?.height !== imgCK[0]?.height)) {
                    message.error('上传组图,需要图片尺寸相同')
                    return
                }
            }
            setImgs([...imgs, img])
            imgMessage([...imgs, img]).then((res: any) => {
                if (res && res?.length > 0) {
                    setImgLength({ width: res[0]?.width || 800, height: res[0]?.height })
                }
            })
        }
    }, [imgs, imgLength])

    /** 上传创意 确定  */
    const handleOk = useCallback(async () => {
        let {labels, media, type, channel, id, title, article, dataType} = queryForm
        setLoading(true)
        if(labels.length === 0) { message.error('请选择标签'); return }
        if(!type) { message.error('请选择类型'); return }
        if(!channel) { message.error('请选择投放渠道'); return }
        if(!dataType) { message.error('请选择数据类型'); return }
        if(editData && typeof editData === 'object' && Object.keys(editData).length > 0) {// 修改
            editIdeas.run({media, type, labels: labels.toString(), id, channel, title, article, dataType}).then(res => {
                setLoading(false)
                setQueryForm({title: '', labels: [], type: 1})
                hideModal()
                ajax?.refresh()
            })
        }else {  // 新增
            if(type === 1) { // 图片
                if(imgs.length === 0) {  message.error('请选择图片'); return }
                let singleImg = true
                if(imgs.length > 1) {
                    singleImg = false
                }
                let md5s: any = []
                let newImgs: File[] = []
                for (let item of imgs) {
                    let file = await dataURLtoFile(item, Math.round(new Date() as any / 1000))
                    let md5 = await getMD5(file)
                    newImgs.push(file)
                    md5s.push(md5)
                }
                let ajaxs = newImgs.map((item) => {
                    return request(`${api}/ads/oss/ossUpload?type=image/jpeg&fileType=image`).then(res => {
                        let formData = new FormData();
                        Object.keys(res.data).forEach((key: string) => {
                            if (key !== 'url') {
                                formData.append(key, res.data[key])
                            }
                        })
                        formData.append('file', item)
                        return request(res?.data?.ossUrl, { method: 'post', body: formData })
                    })
                })
                let imgInfo = await imgMessage(imgs)
                Promise.all(ajaxs).then(res => {
                    let contents = res?.map((item: any) => {
                        return item?.data?.url
                    })
                    if (contents && contents?.length > 0 && contents?.every(item => item)) {
                        addIdeas.run({media: contents.toString(), type, labels: labels.toString(), singleImg, channel, dataType, title, article, width: imgInfo[0]?.width, height: imgInfo[0]?.height, mediaSize: newImgs?.map(item => item?.size)?.toString(), mediaFormat: newImgs?.map(item => 'JPEG')?.toString(), signature: md5s?.toString()}).then(res => {
                            message.success('上传成功')
                            setLoading(false)
                            setQueryForm({title: '', labels: [], type: 1})
                            hideModal()
                            ajax?.refresh()
                        })
                    }
                })
            }else{ // 视频
                if(!video) {  message.error('请选择视频'); return }
                let singleImg = true
                let md5: string = await getMD5(video)
                request(`${api}/ads/oss/ossUpload?type=${video?.type}&fileType=video`).then(res => {
                    let formData = new FormData();
                    Object.keys(res.data).forEach((key: string) => {
                        if (key !== 'url') {
                            formData.append(key, res.data[key])
                        }
                    })
                    formData.append('file', video)
                    request(res?.data?.ossUrl, { method: 'post', body: formData }).then(res => {
                        message.success('上传成功, 视频长宽等数据正在更新中...')
                        addIdeas.run({media: res.data.url, type, labels: labels.toString(), singleImg, dataType, channel, title, article, signature: md5}).then(res => {
                            setLoading(false)
                            setQueryForm({title: '', labels: [], type: 1})
                            hideModal()
                            ajax?.refresh()
                        })
                    })
                })
            }
        }
        
    }, [queryForm, imgs, loading])

    // 获取图片宽高
    const imgMessage = (imgs: string[]): Promise<{width: number, height: number}[]> => {
        return new Promise((resolve, reject) => {
            if (imgs.length > 0) {
                let imgsAll = imgs?.map((item: string) => {
                    return new Promise((resolve) =>{
                        let img: any = new Image();
                        img.onload = function (e: any) {
                            resolve({width: this.width, height: this.height})
                        }
                        img.src = item;
                    })
                })
                Promise.all(imgsAll).then((res: any) => {
                    resolve(res)
                })
            } else {
                reject([])
            }
        })
    }

    // base64转File
    const dataURLtoFile = (dataurl: any, filename: any) => {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, {type:mime});
    }

    const del = useCallback((src: string)=>{
        let newImgs = imgs.filter((item: string) => item !== src)
        setImgs(newImgs)
    },[imgs])

    return <Modal visible={visible} title={
            <>
                <Space>
                    <span>上传创意</span>
                    <Select value={queryForm.type} disabled={queryForm?.id} onChange={(value: SelectValue)=>{setQueryForm({...queryForm, type: value})}} placeholder="选择类型">
                        <Option value={1}>图片</Option>
                        <Option value={2}>视频</Option>
                    </Select>
                </Space>
            </>
        }
        onOk={handleOk} onCancel={hideModal}
        footer={
            <>
                <Space>
                    <Button onClick={hideModal}>取消</Button>
                    <Button type="primary" onClick={handleOk} loading={addIdeas?.loading || editIdeas?.loading || loading}>{editData && typeof editData === 'object' && Object.keys(editData).length > 0 ? '修改' : '新增'}</Button>
                </Space>
            </>
        }
    >
        <Form labelCol={{ span: 4 }}>
            {
                queryForm?.type === 1 ? <Form.Item >
                    {
                        !queryForm?.id && <Cropprt isChangeCropperSize={imgs.length > 0} {...imgLength} callback={(img) => { setImgsHandle(img) }} />
                    }
                    {
                        imgs.length > 0 && <div className={style.imgs}>
                            <Space>
                                {imgs?.map((item: string, index: number) => (
                                    <div className={style.imgCon} key={index}>
                                        <AntImg width={60} src={item} preview={false}/>
                                        {!queryForm?.id && <div className={style.handle}>
                                            <Space><div className={style.bt} onClick={()=>{del(item)}}><DeleteOutlined style={{color: 'red'}}/></div></Space>
                                        </div>}
                                    </div>
                                ))}
                            </Space>
                        </div>
                    }
                    
                </Form.Item> :
                queryForm?.type === 2 ? <Form.Item>
                    {
                        !queryForm?.id ? <Dragger 
                            accept="video/*"
                            action=""
                            customRequest={()=>{}}
                            maxCount={1}
                            fileList={fileList}
                            multiple={false}
                            beforeUpload={(file: RcFile, FileList: RcFile[]) : any=>{
                                const isLt2M = file.size / 1024 / 1024 < 500;
                                if (!isLt2M) {
                                message.error('请上传视频小于 500MB!');
                                return isLt2M;
                                }
                                setFileList(FileList)
                                setVideo(file)
                            }}
                        >
                            <p className="ant-upload-drag-icon">
                            <InboxOutlined />
                            </p>
                            <p className="ant-upload-text">单击或拖动文件到此区域以上载</p>
                            <p className="ant-upload-hint">
                                支持MP4....
                            </p>
                        </Dragger> :
                        <video style={{width: '100%'}} height={160} src={queryForm?.media} loop={true} autoPlay={false} controls></video>
                    }
                </Form.Item> : null
            }
            <Form.Item label="标题">
                <Input disabled={queryForm?.id} value={queryForm.title} onChange={(e)=>{setQueryForm({...queryForm, title: e.target.value})}} placeholder="请输入标题"/>
            </Form.Item>
            <Form.Item label="文案">
                <TextArea
                    disabled={queryForm?.id}
                    value={queryForm.article}
                    placeholder="请输入文案"
                    autoSize={{ minRows: 2 }}
                    onChange={(e)=>{setQueryForm({...queryForm, article: e.target.value})}}
                />
            </Form.Item>

            <Form.Item label="标签">
                <Select value={queryForm.labels} onChange={(value: SelectValue)=>{setQueryForm({...queryForm, labels: value})}} placeholder="选择标签" mode="multiple">
                    {getLabels?.data?.records.map((item: any) => (<Option value={item?.label} key={item?.label + item?.id}>{item?.label}</Option>))}
                </Select>
            </Form.Item>
            <Form.Item label="渠道">
                <Select value={queryForm.channel} disabled={queryForm?.id} onChange={(value: SelectValue)=>{setQueryForm({...queryForm, channel: value})}} placeholder="选择投放渠道">
                    {channelCon?.map((item: string, index: number) => <Option value={item} key={index}>{item}</Option>)}
                </Select>
            </Form.Item>
            <Form.Item label="数据类型">
                <Select value={queryForm.dataType} disabled={queryForm?.id && typeData === 'all'} onChange={(value: SelectValue)=>{setQueryForm({...queryForm, dataType: value})}} placeholder="选择数据类型">
                    <Option value='personal' disabled={queryForm?.id && typeData === 'group'}>个人</Option>
                    <Option value='group'>组内共享</Option>
                    <Option value='all'>公司全员共享</Option>
                </Select>
            </Form.Item>
        </Form>
    </Modal>
}

export default React.memo(AddOriginality)