import React, { useEffect, useState, useRef } from 'react';
import { __ } from '@wordpress/i18n';
import { head, isEmpty } from 'ramda';

import { FileUpload } from 'primereact/fileupload';
import { Tag } from 'primereact/tag';
import { Button } from 'primereact/button';

// api
import ApplicationService from '../../service/application-service';

import { defaultMaxFileSize, mimeTypes } from '../../configData';

const FileuploadApplicationSignedPdf = ({
                                            fieldName,
                                            setDataFn,
                                            defaultValue = [],
                                            accept = [],
                                            maxSize = defaultMaxFileSize,
                                            emptyText = __('Trascina qui il tuo file', 'gepafin'),
                                            chooseLabel = __('Aggiungi documento', 'gepafin'),
                                            uploadLabel = __('Salva documento', 'gepafin'),
                                            cancelLabel = __('Cancella documento', 'gepafin'),
                                            multiple = false,
                                            applicationId = 0,
                                            disabled = false
                                        }) => {
    const [stateFieldData, setStateFieldData] = useState([]);
    const [acceptFormats, setAcceptFormats] = useState('');
    const [formatsForInput, setFormatsForInput] = useState('');
    const inputRef = useRef();

    const customBase64Uploader = (event) => {
        const formData = new FormData()
        for (const file of event.files) {
            formData.append('file', file)
        }
        ApplicationService.uploadApplicationSignedPdf(applicationId, formData, callback, errorCallback);
    };

    const callback = (data) => {
        if (data.status === 'SUCCESS') {
            setStateFieldData([data.data]);
            inputRef.current.setFiles([]);
        }
    }

    const errorCallback = (err) => {
        console.log('err', err);
    }

    const itemTemplate = (file) => {
        let fileName = file.fileName ? file.fileName : file.name;
        return (
            <div className="appForm__fileUploadItem">
                <div>
                    <span className="appForm__fileUploadItemName">
                        {fileName}
                    </span>
                </div>
                <div>
                    {file.id ? <Tag value={__('Caricato', 'gepafin')} severity="success"></Tag> : null}
                    {!file.id ? <Tag value={__('In attesa', 'gepafin')} severity="warning"></Tag> : null}
                </div>
                <div>
                    <Button
                        type="button"
                        disabled={disabled}
                        icon="pi pi-times"
                        severity="danger"
                        aria-label={__('Annulla', 'gepafin')}
                        onClick={() => onTemplateRemove(file)}/>
                </div>
            </div>
        );
    };

    const onTemplateRemove = (file) => {
        if (file.id) {
            ApplicationService.deleteApplicationSignedPdf(
                applicationId,
                (data) => dCallback(data, file.id),
                dErrorCallback
            );
        } else {
            const files = inputRef.current.getFiles()
            const newFiles = files.filter(o => o.lastModified !== file.lastModified && o.name !== file.name);
            inputRef.current.setFiles(newFiles);
        }
    }

    const dCallback = (data, id) => {
        if (data.status === 'SUCCESS') {
            setStateFieldData(prevState => {
                const newFiles = prevState.filter(o => o.id !== id);
                inputRef.current.setUploadedFiles(newFiles);
                return newFiles;
            });
        }
    }

    const dErrorCallback = (err) => {
        console.log('err', err);
    }

    const onBeforeDrop = (e) => {
        return !isEmpty(e.dataTransfer.files) ? validateFileInputType(e.dataTransfer.files) : false;
    }

    const onBeforeSelect = (e) => {
        const files = inputRef.current.getFiles();
        const uploadedfiles = inputRef.current.getUploadedFiles();

        if (!multiple && (uploadedfiles.length > 0 || files.length > 0)) {
            return false;
        }

        if (e.originalEvent.target.files) {
            return !isEmpty(e.originalEvent.target.files)
                ? validateFileInputType(e.originalEvent.target.files)
                : false;
        }
    }

    const validateFileInputType = (files) => {
        const MIMEtype = new RegExp(acceptFormats);

        return Array.prototype.every.call(files, function passesAcceptedFormat(file) {
            const fileExtension = `.${file.name.split('.').pop().toLowerCase()}`;
            const fileType = file.type;
            if (file.size === 0) {
                alert('Il file non è valido');
            }
            return file.size > 0 && (MIMEtype.test(fileType) || MIMEtype.test(fileExtension));
        });
    }

    useEffect(() => {
        setStateFieldData(defaultValue);
    }, []);

    useEffect(() => {
        if (inputRef.current) {
            inputRef.current.setUploadedFiles(defaultValue);
        }
    }, [defaultValue]);

    useEffect(() => {
        const properMime = accept.map
            ? accept
                .map(v => {
                    const found = head(mimeTypes.filter(o => o.code.includes(v)));
                    let res = v;

                    if (found) {
                        res = found.code;
                    }

                    return res;
                }) : [];

        // eslint-disable-next-line no-useless-escape
        setAcceptFormats(properMime.join(',').replace(/\*/g, '.\*').replace(/,/g, '|'));
        setFormatsForInput(properMime.join(','));
    }, [accept]);

    useEffect(() => {
        if (inputRef.current) {
            inputRef.current.setUploadedFiles(stateFieldData ? stateFieldData : []);
        }
        setDataFn(fieldName, stateFieldData, { shouldValidate: true });
    }, [stateFieldData])

    return (
        applicationId && applicationId !== 0
            ? <FileUpload
                ref={inputRef}
                disabled={disabled}
                id={fieldName}
                name={fieldName}
                url={'/document/uploadFile'}
                multiple={multiple}
                accept={formatsForInput}
                maxFileSize={maxSize}
                emptyTemplate={<p>{emptyText}</p>}
                chooseLabel={chooseLabel}
                cancelLabel={cancelLabel}
                uploadLabel={uploadLabel}
                itemTemplate={itemTemplate}
                customUpload
                onBeforeDrop={onBeforeDrop}
                onBeforeSelect={onBeforeSelect}
                uploadHandler={customBase64Uploader}/>
            : null
    )
}

export default FileuploadApplicationSignedPdf;