import React, { useCallback, useEffect, useState } from 'react'
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";
import { Button, Col, Form, InputNumber, message, Radio, Row, Spin, Upload } from 'antd';
import Modal from 'antd/lib/modal/Modal';
import { RcFile } from 'antd/lib/upload';
import { InboxOutlined } from '@ant-design/icons'
const { Dragger } = Upload
import { compressAccurately } from 'image-conversion';
import { blobToBase64 } from '@/utils/compress'

interface Props {
    width?: number,//初始裁剪框宽
    height?: number,//初始裁剪框高
    imgSize?: { width: number, height: number, size: number },
    disabled?: boolean, // 是否禁止传入
    btnName?: string | JSX.Element//按钮名称
    isChangeCropperSize?: boolean,  // 是否可以改变裁剪框大小
    isLaunch?: boolean, // 是否是在落地页上传
    isCropper?: boolean, // 是否需要裁剪
    isJudgeSize?: boolean,   // 是否判断图片宽高与传入的裁剪框宽高 图片大小需要大于裁剪框大小
    callback?: (imgData: any) => void//裁剪后图片的数据
}
/**图片裁剪
 * @param width 初始裁剪框宽
 * @param height 初始高度
 * @param btnName 按钮名称
 * @param disabled 是否禁止传入
 * @param isLaunch 是否是在落地页上传
 * @param isCropper 是否需要裁剪
 * @param callback 裁剪后图片的数据的回调函数
 * @param isJudgeSize 是否判断图片宽高与传入的裁剪框宽高 图片大小需要大于裁剪框大小 需传入width和height
 */
export const Demo = (props: Props) => {

    let { isJudgeSize = false, isChangeCropperSize = false, isLaunch = false, isCropper = false, disabled = false, imgSize } = props
    const [image, setImage] = useState('');//初始图片
    const [visible, setVisible] = useState<boolean>(false)
    const [cropper, setCropper] = useState<any>();//实例
    const [loading, setLoading] = useState<boolean>(false)
    const [detail, setDetail] = useState<{ width: number, height: number, rotate: number }>({ width: props?.width || 800, height: props?.height || 800, rotate: 0 });//设置数据

    /**关闭 */
    const cancel = useCallback(() => {
        setVisible(false)
        setCropper(undefined)
        setImage('')
    }, [])
    /**获取裁剪数据*/
    const getCropData = () => {
        if (typeof cropper !== "undefined") {
            props?.callback && props?.callback(cropper.getCroppedCanvas().toDataURL('image/jpeg'))
            cancel()
        }
    };
    /**数值变化重置实例 */
    useEffect(() => {
        if (typeof cropper !== "undefined") {
            cropper.setData(detail);
        }
    }, [cropper, detail]);

    useEffect(() => {
        if (visible && cropper) {
            setTimeout(() => {
                cropper.reset()
                if (props?.width) {
                    cropper.setData({ width: props?.width, height: props?.height })
                }
            }, 200)
        }
    }, [visible, cropper])

    return <Spin spinning={loading}>
        {
            <Dragger
                disabled={disabled}
                accept="image/*"
                action="#"
                showUploadList={false}
                multiple={true}
                customRequest={() => { }}
                beforeUpload={(file: RcFile, FileList: RcFile[]): any => {
                    setLoading(true)
                    let img: any = new Image();
                    let _URL = window.URL || window.webkitURL;
                    img.onload = function (e: any) {
                        if (isJudgeSize) {
                            if (!props?.width || !props?.height) {
                                console.error('请传入"width"与"height"');
                                setLoading(false)
                                return
                            } else if (props?.width < this.width || props?.height < this.height) {
                                message.error(`传入的图片大小不符, 图片大小${this.width}*${this.height}, 需要图片大小${props.width}*${props.height}`)
                                setLoading(false)
                                return
                            }
                        }

                        const reader = new FileReader();
                        reader.onload = async () => {
                            let size = imgSize?.size || 307200
                            if (isCropper) {
                                setImage(reader.result as any);
                                setLoading(false)
                            } else {
                                if (imgSize && (imgSize?.width === 800 || imgSize?.width === 640 || imgSize?.width === 960)) {
                                    if (imgSize?.width !== this.width || imgSize?.height !== this.height) {
                                        message.error(`请上传${imgSize?.width} * ${imgSize?.height}尺寸图片`)
                                        setLoading(false)
                                        return
                                    }
                                } else if (imgSize?.width === 750) {
                                    if (imgSize?.width !== this.width || this.height > 1536) {
                                        message.error(`请上传${imgSize?.width} * <1536尺寸图片`)
                                        setLoading(false)
                                        return
                                    }
                                }
                                if (size === 307200 && file?.size > size) { // 大于300kb进入压缩
                                    let bole = await compressAccurately(file, 250)
                                    if (bole?.size > 300000) {
                                        bole = await compressAccurately(file, 200)
                                    }
                                    if (bole?.size > 300000) {
                                        bole = await compressAccurately(file, 150)
                                    }
                                    if (bole?.size > 300000) {
                                        bole = await compressAccurately(file, 100)
                                    }
                                    let newFile = await blobToBase64(bole)
                                    message.warning({
                                        content: '选择的图片大于300KB，图片已压缩',
                                        duration: 3
                                    })
                                    props?.callback && props?.callback(newFile);
                                    setLoading(false)
                                    return
                                } else if (size === 81920 && file?.size > size) {
                                    let bole = await compressAccurately(file, 80)
                                    if (bole?.size > 80000) {
                                        bole = await compressAccurately(file, 60)
                                    }
                                    if (bole?.size > 80000) {
                                        bole = await compressAccurately(file, 40)
                                    }
                                    let newFile = await blobToBase64(bole)
                                    message.warning({
                                        content: '选择的图片大于80KB，图片已压缩',
                                        duration: 3
                                    })
                                    props?.callback && props?.callback(newFile);
                                    setLoading(false)
                                    return
                                }
                                props?.callback && props?.callback(reader.result);
                                setLoading(false)
                            }
                        };
                        reader.readAsDataURL(file);
                        if (isCropper) {
                            setLoading(false)
                            setVisible(true)
                        }

                    }
                    img.src = _URL.createObjectURL(file);

                }}
            >
                {
                    props?.btnName ? props?.btnName : <>
                        <p className="ant-upload-drag-icon">
                            <InboxOutlined />
                        </p>
                        <p className="ant-upload-text">单击或拖动文件到此区域以上载</p>
                        <p className="ant-upload-hint">支持jpg,png...</p>
                    </>
                }
            </Dragger>
        }
        {visible && <Modal
            open={visible}
            onCancel={cancel}
            width={1000}
            footer={<div style={{ display: 'flex', justifyContent: 'center' }}>
                <Button onClick={cancel}>取消</Button>
                {/* <Button onClick={() => {
                    cropper.reset()
                    if (props?.width) {
                        cropper.setData({ width: props?.width, height: props?.height })
                    }
                }}>重置</Button> */}
                <Button type='primary' onClick={getCropData}>确定</Button>
            </div>}
        >
            <div>
                <div style={{ width: "100%" }}>
                    <Row>
                        <Col span={16}>
                            <Cropper
                                style={{ height: 400, width: 600, backgroundImage: `url(${require('../../../public/init.png')})`, border: '1px solid #efefef' }}
                                zoomTo={0.6}
                                initialAspectRatio={1}
                                preview=".img-preview"
                                src={image}
                                viewMode={0}
                                guides={true}
                                rotatable={true}
                                minCropBoxHeight={10}
                                minCropBoxWidth={10}
                                background={false}
                                responsive={true}
                                autoCropArea={1}
                                cropBoxResizable={false}
                                checkOrientation={false}
                                onInitialized={(instance: any) => {
                                    setCropper(instance);
                                }}
                            />
                        </Col>
                        <Col span={8}>
                            <Row gutter={[10, 10]}>
                                <Col span={24} style={{ height: 275 }}>
                                    <div className="box" style={{ width: "100%", float: "right", overflow: 'hidden' }}>
                                        <h1>Preview</h1>
                                        <div
                                            className="img-preview"
                                            style={{ width: "100%", float: "left", height: "200px", overflow: 'hidden' }}
                                        />
                                    </div>
                                </Col>
                                <Col>
                                    <Form>
                                        <Form.Item label="裁剪框宽" style={{ marginBottom: 0 }}>
                                            <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e) => { setDetail({ ...detail, width: e.target.value, height: 800 }) }} value={detail.width}>
                                                <Radio value={800}>800</Radio>
                                                <Radio value={750}>750</Radio>
                                                <Radio value={640}>640</Radio>
                                            </Radio.Group>
                                        </Form.Item>
                                        <Form.Item label="裁剪框高" style={{ marginBottom: 0 }}>
                                            {detail.width === 800 ? <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e) => { setDetail({ ...detail, height: e.target.value }) }} value={detail.height}>
                                                <Radio value={800}>800</Radio>
                                                <Radio value={640}>640</Radio>
                                                <Radio value={450}>450</Radio>
                                            </Radio.Group>
                                                : detail.width === 640 ? <Radio.Group disabled={isChangeCropperSize || isLaunch} onChange={(e) => { setDetail({ ...detail, height: e.target.value }) }} value={detail.height}>
                                                    <Radio value={800}>800</Radio>
                                                </Radio.Group>
                                                    :
                                                    <InputNumber
                                                        style={{ width: 200 }}
                                                        value={detail.height}
                                                        disabled={isChangeCropperSize ? isChangeCropperSize : isLaunch ? false : false}
                                                        min={1}
                                                        max={1536}
                                                        onChange={(e) => { setDetail({ ...detail, height: e || 0 }) }}
                                                    />
                                            }
                                        </Form.Item>

                                    </Form>
                                </Col>
                            </Row>
                        </Col>
                    </Row>
                </div>
            </div>
        </Modal>}
    </Spin>
};

export default Demo;
