import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { __ } from '@wordpress/i18n';
import { classNames } from 'primereact/utils';
import { wrap } from 'object-path-immutable';
import { head, isEmpty, isNil } from 'ramda';

// store
import { storeSet, useStoreValue } from '../../store';

// api
import DocumentCategoryService from '../../service/document-category-service';
import CompanyDocumentsService from '../../service/company-documents-service';

// components
import DocumentsTable from './components/DocumentsTable';
import { Dialog } from 'primereact/dialog';
import { Button } from 'primereact/button';
import { Dropdown } from 'primereact/dropdown';
import { InputText } from 'primereact/inputtext';
import { Calendar } from 'primereact/calendar';
import { FileUpload } from 'primereact/fileupload';
import formatDateString from '../../helpers/formatDateString';
import { Link } from 'react-router-dom';


const DocumentsBeneficiary = () => {
    const [loading, setLoading] = useState(false);
    const chosenCompanyId = useStoreValue('chosenCompanyId');
    const companies = useStoreValue('companies');
    const [isVisibleAddNewDialog, setIsVisibleAddNewDialog] = useState(false);
    const documentCategories= useStoreValue('documentCategories');
    const [newFileData, setNewFileData] = useState({});
    const [fileAttached, setFileAttached] = useState([]);
    const [reloadHash, setReloadHash] = useState(0);
    const tomorrow = useMemo(() => {
        const d = new Date();
        d.setDate(d.getDate() + 1);
        return d;
    }, []);
    const company = head(companies.filter(o => o.id === chosenCompanyId));

    const onCreateNew = useCallback((type) => {
        const newData = wrap({})
            .set(['documentType'], type)
            .set(['documentCategoryId'], 0)
            .set(['expirationDate'], '')
            .set(['name'], '')
            .value();

        setNewFileData(newData);
        setFileAttached([]);
        setIsVisibleAddNewDialog(true);
    }, [newFileData, chosenCompanyId]);

    const hideAddNewDialog = () => {
        setIsVisibleAddNewDialog(false);
        const newData = wrap({})
            .set(['documentType'], '')
            .set(['documentCategoryId'], 0)
            .set(['expirationDate'], '')
            .set(['name'], '')
            .value();
        setNewFileData(newData);
        setFileAttached([]);
    }

    const headerAddNewDialog = () => {
        return <span>{__('Aggiungi file', 'gepafin')}</span>
    }

    const footerAddNewDialog = () => {
        return <div>
            <Button type="button" label={__('Annulla', 'gepafin')} onClick={hideAddNewDialog} outlined/>
            <Button
                type="button"
                disabled={loading || !isValidForm()}
                label={__('Salva', 'gepafin')} onClick={doAddNew}/>
        </div>
    }

    const isValidForm = useCallback(() => {
        return !isEmpty(fileAttached) && !Object.keys(newFileData).filter(k => isInvalidField(newFileData, k)
            || newFileData[k] === 0).length
    }, [fileAttached, newFileData]);

    const doAddNew = useCallback(() => {
        const submitData = {
            ...newFileData,
            expirationDate: formatDateString(newFileData.expirationDate)
        }
        const queryParams = Object.keys(submitData).map(k => [
            k, submitData[k]
        ]);

        if (!isEmpty(fileAttached)) {
            const formData = new FormData()
            for (const file of fileAttached) {
                formData.append('file', file)
            }
            setLoading(true);
            CompanyDocumentsService.uploadCompanyDocument(chosenCompanyId, formData, uploadDoc, errUploadDoc, queryParams);
        }
    }, [fileAttached, newFileData, chosenCompanyId]);

    const uploadDoc = (resp) => {
        if (resp.status === 'SUCCESS') {
            hideAddNewDialog();
            setReloadHash(new Date().getTime())
        }
        setLoading(false);
    }

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

    const isInvalidField = (data, key) => isEmpty(data[key]) || isNil(data[key]);

    const onUpdateFieldValue = useCallback((value, name) => {
        const newData = wrap(newFileData).set([name], value).value();
        setNewFileData(newData);
    }, [newFileData]);

    const onFileSelect = (file) => {
        setFileAttached(file.files);
    }

    const getCategories = (resp) => {
        if (resp.status === 'SUCCESS') {
            storeSet('documentCategories', resp.data.map(o => ({value: o.id, label: o.description})));
        }
        setLoading(false);
    }

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

    useEffect(() => {
        setLoading(true);
        DocumentCategoryService.getCategories(getCategories, errGetCategories)
    }, []);

    return(
        <div className="appPage">
            <div className="appPage__pageHeader">
                <h1>{__('Gestione documenti', 'gepafin')}</h1>
                {company ? <span className="companyName">{company.companyName}</span> : null}
            </div>

            <div className="appPage__spacer"></div>
            {isEmpty(chosenCompanyId) || chosenCompanyId === 0
                ? <>
                    <div className="appPageSection__message warning">
                        <i className="pi pi-exclamation-triangle"></i>
                        <span className="summary">{__('Attenzione', 'gepafin')}</span>
                        <span>
                            {__('Per caricare i file devi Registare un Azienda clicca', 'gepafin')}
                            <Link to={`/agguingi-azienda`} style={{marginLeft: '0.5ch'}}>{__('qua', 'gepafin')}</Link>
                        </span>
                    </div>
                    <div className="appPage__spacer"></div>
                </> : null}

            <div className="appPageSection statsBigBadges">
                <h2>
                    {__('Documenti del rappresentante legale', 'gepafin')}
                    <Button
                        disabled={isEmpty(chosenCompanyId) || chosenCompanyId === 0}
                        onClick={() => onCreateNew('PERSONAL_DOCUMENT')}
                        size="small"
                        label={__('Aggiungi nuovo')} icon="pi pi-plus" iconPos="right"/>
                </h2>
                <DocumentsTable type="PERSONAL_DOCUMENT" reload={reloadHash}/>
            </div>

            <div className="appPage__spacer"></div>

            <div className="appPageSection statsBigBadges">
                <h2>
                    {__('Documenti dell\'azienda', 'gepafin')}
                    <Button
                        disabled={isEmpty(chosenCompanyId) || chosenCompanyId === 0}
                        onClick={() => onCreateNew('COMPANY_DOCUMENT')}
                        size="small"
                        label={__('Aggiungi nuovo')} icon="pi pi-plus" iconPos="right"/>
                </h2>
                <DocumentsTable type="COMPANY_DOCUMENT" reload={reloadHash}/>
            </div>

            <Dialog
                visible={isVisibleAddNewDialog}
                modal
                header={headerAddNewDialog}
                footer={footerAddNewDialog}
                style={{ maxWidth: '600px', width: '100%' }}
                onHide={hideAddNewDialog}>
                <div className="appForm__cols">
                    <div className="appForm__field">
                        <label
                            className={classNames({ 'p-error': isInvalidField(newFileData, 'name') })}>
                            {__('Nome', 'gepafin')}*
                        </label>
                        <InputText value={newFileData.name}
                                   invalid={isInvalidField(newFileData, 'name')}
                                   onChange={(e) => onUpdateFieldValue(e.target.value, 'name')}/>
                    </div>
                    <div className="appForm__field">
                        <label
                            className={classNames({ 'p-error': isInvalidField(newFileData, 'documentCategoryId') || newFileData.documentCategoryId === 0 })}>
                            {__('Categoria', 'gepafin')}*
                        </label>
                        <Dropdown
                            value={newFileData.documentCategoryId}
                            invalid={isEmpty(newFileData.documentCategoryId) || isNil(newFileData.documentCategoryId) || newFileData.documentCategoryId === 0}
                            onChange={(e) => onUpdateFieldValue(e.value, 'documentCategoryId')}
                            options={documentCategories}
                            optionLabel="label"
                            optionValue="value"/>
                    </div>
                </div>
                <div className="appForm__cols">
                    <div className="appForm__field">
                        <label
                            className={classNames({ 'p-error': isEmpty(newFileData.expirationDate) || isNil(newFileData.expirationDate) })}>
                            {__('Scadenza', 'gepafin')}*
                        </label>
                        <Calendar
                            value={newFileData.expirationDate}
                            minDate={tomorrow}
                            invalid={isEmpty(newFileData.expirationDate) || isNil(newFileData.expirationDate) || newFileData.expirationDate === 0}
                            onChange={(e) => onUpdateFieldValue(e.value, 'expirationDate')}/>
                    </div>
                </div>
                <div className="appForm__cols">
                    <div className="appForm__field">
                        <label
                            className={classNames({ 'p-error': isEmpty(newFileData.file) || isNil(newFileData.expirationDate) })}>
                            {__('File', 'gepafin')}*
                        </label>
                        <FileUpload
                            mode="basic"
                            name="file"
                            onSelect={onFileSelect}/>
                    </div>
                </div>
            </Dialog>
        </div>
    )
}

export default DocumentsBeneficiary;