import React, { useCallback, useEffect, useRef, useState } from 'react';
import { classNames } from 'primereact/utils';
import { __ } from '@wordpress/i18n';
import { isEmpty, isNil, pathOr, pluck } from 'ramda';

// service
import FileUploadService from '../../../../service/file-upload-service';
import CompanyDocumentsService from '../../../../service/company-documents-service';

// components
import { ListBox } from 'primereact/listbox';
import { Button } from 'primereact/button';
import { Link } from 'react-router-dom';
import { ConfirmPopup, confirmPopup } from 'primereact/confirmpopup';

const FileSelect = ({
                        fieldName,
                        label,
                        setDataFn,
                        register,
                        errors,
                        defaultValue,
                        config = {},
                        infoText = null,
                        disabled = false,
                        options = [],
                        sourceId = 0,
                        source = 'DOCUMENT',
                        documentCategories = [],
                        saveFormCallback,
                        attachFilesCallback,
                    }) => {
    //const [stateFieldData, setStateFieldData] = useState([]);
    const stateFieldData = useRef([]);
    const [selectedUnconfirmed, setSelectedUnconfirmed] = useState([]);
    const [optionsTransformed, setOptionsTransformed] = useState([]);
    const [loading, setLoading] = useState(false);
    const [addNewMode, setAddNewMode] = useState(false);

    const attachSelectedFiles = useCallback(() => {
        const existingIds = pluck('id', stateFieldData.current);
        const selectedToBeAdded = selectedUnconfirmed.filter(o => !existingIds.includes(o.id));
        setSelectedUnconfirmed([]);

        setLoading(true);
        // eslint-disable-next-line array-callback-return
        selectedToBeAdded.map(o => {
            CompanyDocumentsService.attachCompanyDocumentToAppl(o.id, callback, errCallback, [
                ['applicationId', sourceId],
                ['documentType', source]
            ])
        });
        setAddNewMode(false);
    }, [selectedUnconfirmed]);

    const attachSelectedFilesCallback = useCallback(() => {
        const existingIds = pluck('id', stateFieldData.current);
        const selectedToBeAdded = selectedUnconfirmed.filter(o => !existingIds.includes(o.id));
        setSelectedUnconfirmed([]);

        // eslint-disable-next-line array-callback-return
        selectedToBeAdded.map(o => attachFilesCallback(o));
        setAddNewMode(false);
    }, [selectedUnconfirmed]);

    const doGoBackToListOfFiles = () => {
        setSelectedUnconfirmed([]);
        setAddNewMode(false);
    }

    const callback = (resp) => {
        if (resp.status === 'SUCCESS') {
            stateFieldData.current = [...stateFieldData.current, resp.data];
            setDataFn(fieldName, stateFieldData.current, { shouldValidate: true });
            saveFormCallback();
        }
        setLoading(false);
    }

    const errCallback = () => {
        setLoading(false);
    }

    const removeAttached = (id) => {
        FileUploadService.deleteFile(
            {},
            (data) => deleteCallback(data, id),
            deleteErrorCallback,
            [['id', id]]
        );
    }

    const deleteCallback = (data, id) => {
        if (data.status === 'SUCCESS') {
            stateFieldData.current = stateFieldData.current.filter(o => id !== o.id);
            setDataFn(fieldName, stateFieldData.current, { shouldValidate: true });
            saveFormCallback();
        }
    }

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

    const confirmDelete = (event, id) => {
        confirmPopup({
            target: event.currentTarget,
            message: __('Sei sicuro di cancellare il file?', 'gepafin'),
            acceptLabel: __('Si', 'gepafin'),
            icon: 'pi pi-info-circle',
            defaultFocus: 'reject',
            acceptClassName: 'p-button-danger',
            accept: () => removeAttached(id),
            reject: () => {
            }
        });
    };

    useEffect(() => {
        stateFieldData.current = defaultValue;
        register(fieldName, config)
    }, []);

    useEffect(() => {
        if (!isEmpty(options)) {
            const optionsDefault = options
                .filter(o => isEmpty(documentCategories)
                    ? o
                    : documentCategories.includes(o.category.id))
                .reduce((acc, cur) => {
                    const catName = pathOr('', ['category', 'categoryName'], cur);
                    const catLabel = pathOr('', ['category', 'description'], cur);

                    if (!acc[catName]) {
                        acc[catName] = {
                            code: catName,
                            label: catLabel,
                            items: []
                        };
                    }
                    acc[catName].items.push(cur)
                    return acc;
                }, {});

            setOptionsTransformed(Object.values(optionsDefault));
        }
    }, [options]);

    useEffect(() => {
        stateFieldData.current = defaultValue;
    }, [defaultValue]);

    return (
        <>
            {!isNil(label)
                ? <label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] })}>
                    {label}{config.required || config.isRequired ?
                    <span className="appForm__field--required">*</span> : null}
                </label> : null}
            <div className="fileselectInner">
                {addNewMode
                    ? <div className="fileselectInner__selectionBox">
                        <ListBox multiple
                                 value={selectedUnconfirmed}
                                 onChange={(e) => setSelectedUnconfirmed(e.value)}
                                 options={optionsTransformed}
                                 optionLabel="name"
                                 optionGroupLabel="label"
                                 optionGroupChildren="items"
                                 className="w-full md:w-14rem"
                                 listStyle={{ maxHeight: '130px' }}/>
                        {!isEmpty(selectedUnconfirmed)
                            ? <Button
                                severity="success"
                                disabled={loading}
                                onClick={!isNil(attachFilesCallback) ? attachSelectedFilesCallback : attachSelectedFiles}
                                label={__('Conferma i file scelti', 'gepafin')}
                                icon="pi pi-arrow-right" size="small" iconPos="right"/>
                            : <Button
                                severity="success"
                                outlined
                                onClick={doGoBackToListOfFiles}
                                label={__('Torna alla lista dei file selezionati', 'gepafin')}
                                icon="pi pi-arrow-right" size="small" iconPos="right"/>}
                    </div> : null}
                {!isEmpty(optionsTransformed) && !addNewMode
                    ? <div className="fileselectInner__selectedFiles">
                        <p><strong>{__('I file selezionati:')}</strong></p>
                        <ul>
                            {!isEmpty(stateFieldData.current)
                                ? [...stateFieldData.current].map(o => <li key={o.id}>
                                    {o.name}
                                    {isNil(attachFilesCallback)
                                        ? <div className="appPageSection__iconActions">
                                            <Button icon="pi pi-times" rounded
                                                    type="button"
                                                    size="small"
                                                    onClick={(e) => confirmDelete(e, o.id)}
                                                    outlined severity="danger"
                                                    aria-label={__('Cancella', 'gepafin')}/>
                                        </div> : null}
                                </li>) : <li>{__('Nessun file selezionato', 'gepafin')}</li>}
                        </ul>
                        <Button
                            severity="success"
                            disabled={loading}
                            onClick={() => setAddNewMode(true)}
                            label={__('Aggiungi i file', 'gepafin')}
                            icon="pi pi-plus" size="small" iconPos="right"/>
                    </div> : null}
            </div>
            {isEmpty(optionsTransformed)
                ? <div className="appPageSection__message warning">
                    <span>
                        {__('I file caricati sulla pagina Documenti saranno disponibili qui. ', 'gepafin')}
                        <Link to={`/documenti`}>
                            {__('Vai alla pagina Documenti', 'gepafin')}
                        </Link>
                    </span>
                </div>
                : null}
            {infoText ? <small>{infoText}</small> : null}
            <ConfirmPopup/>
        </>)
}

export default FileSelect;