import React, { useEffect, useRef, useState } from 'react';
import { __ } from '@wordpress/i18n';
import { is, isEmpty, isNil } from 'ramda';
import { wrap } from 'object-path-immutable';

// tools
import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
import uniqid from '../../../../helpers/uniqid';
import getFormatedFileSizeText from '../../../../helpers/getFormatedFileSizeText';

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

// api
import CommunicationService from '../../../../service/communication-service';

// components
import { Button } from 'primereact/button';
import { classNames } from 'primereact/utils';
import { InputText } from 'primereact/inputtext';
import { Dialog } from 'primereact/dialog';
import { Toast } from 'primereact/toast';
import { FileUpload } from 'primereact/fileupload';
import { defaultMaxFileSize, mimeTypes } from '../../../../configData';
import { Editor } from 'primereact/editor';
import renderHtmlContent from '../../../../helpers/renderHtmlContent';

const SoccorsoComunications = ({amendmentId, soccorsoStatus}) => {
    const [comms, setComms] = useState([]);
    const [isVisibleNewCommDialog, setIsVisibleNewCommDialog] = useState(false);
    const [newCommData, setNewCommData] = useState({});
    const [isLoadingCommunication, setIsLoadingCommunication] = useState(false);
    const toast = useRef(null);
    const commDialogFilesRef = useRef(null);
    const role = useStoreValue('getRole');

    useEffect(() => {
        if (amendmentId && amendmentId !== 0) {
            setIsLoadingCommunication(true);
            CommunicationService.getCommsByAmendmentId(amendmentId, getCommsCallback, errGetCommsCallback);
        }
    }, [amendmentId]);

    const getCommsCallback = (data) => {
        if (data.status === 'SUCCESS') {
            setComms(data.data.map(o => getFormattedCommsData(o)));
        }
        setIsLoadingCommunication(false);
    };

    const errGetCommsCallback = (data) => {
        if (toast.current && data.message) {
            toast.current.show({
                severity: 'error',
                summary: '',
                detail: data.message
            });
        }
        setIsLoadingCommunication(false);
    };

    const getFormattedCommsData = (data) => {
        data.id = isNil(data.id) ? uniqid('id') : data.id;
        data.commentedDate = is(String, data.commentedDate) ? new Date(data.commentedDate) : (data.commentedDate ? data.commentedDate : '');
        data.createdDate = is(String, data.createdDate) ? new Date(data.createdDate) : (data.createdDate ? data.createdDate : '');
        data.updatedDate = is(String, data.updatedDate) ? new Date(data.updatedDate) : (data.updatedDate ? data.updatedDate : '');
        return data;
    };

    const headerNewComDialog = () => {
        return <span>{__('Aggiungi comunicazione', 'gepafin')}</span>;
    };

    const hideNewComDialog = () => {
        setIsVisibleNewCommDialog(false);
        setNewCommData({
            title: '',
            comment: ''
        });
    };

    const footerNewComDialog = () => {
        return <div>
            <Button type="button" label={__('Annulla', 'gepafin')} onClick={hideNewComDialog} outlined/>
            <Button
                type="button"
                disabled={isLoadingCommunication || isEmpty(newCommData.title) || isEmpty(newCommData.comment)}
                label={__('Invia', 'gepafin')} onClick={createCommunication}/>
        </div>;
    };

    const openNewCommDialog = () => {
        setIsVisibleNewCommDialog(true);
        setNewCommData({
            title: '',
            comment: ''
        });
    };

    const updateNewCommData = (value, path) => {
        const newData = wrap(newCommData).set(path.split('.'), value).value();
        setNewCommData(newData);
    };

    const createCommunication = () => {
        setIsLoadingCommunication(true);
        const updatedFormData = { ...newCommData };
        delete updatedFormData.files;
        const formDataToSend = new FormData();

        const jsonBlob = new Blob([JSON.stringify(updatedFormData)], {
            type: 'application/json'
        });
        formDataToSend.append('communicationRequestBean', jsonBlob);

        if (newCommData.files && newCommData.files.length > 0) {
            newCommData.files.forEach((file) => {
                formDataToSend.append('files', file);
            });
        }

        CommunicationService.createCommunication(amendmentId, formDataToSend, createCommunicationCallback, errCreateCommunicationCallback);
    };

    const createCommunicationCallback = (data) => {
        if (data.status === 'SUCCESS') {
            if (toast.current) {
                toast.current.show({
                    severity: 'success',
                    summary: '',
                    detail: data.message
                });
            }
            setComms([...comms, getFormattedCommsData(data.data)]);
            setIsVisibleNewCommDialog(false);
        }
        setIsLoadingCommunication(false);
    };

    const errCreateCommunicationCallback = (data) => {
        if (toast.current && data.message) {
            toast.current.show({
                severity: 'error',
                summary: '',
                detail: data.message
            });
        }
        set404FromErrorResponse(data);
        setIsLoadingCommunication(false);
    };

    const displayCommIcon = (comm) => {
        const userData = storeGet('userData');
        return userData.id === comm.senderUserId
            ? <i className="pi pi-upload"></i>
            : <i className="pi pi-download"></i>;
    };

    const getCommRowClass = (comm) => {
        const userData = storeGet('userData');
        return userData.id === comm.senderUserId ? 'outgoing' : 'incoming';
    };

    const renderHeader = () => {
        return (
            <span className="ql-formats">
                <button className="ql-bold" aria-label="Bold"></button>
                <button className="ql-italic" aria-label="Italic"></button>
                <button className="ql-underline" aria-label="Underline"></button>
                <button className="ql-link" aria-label="Link"></button>
                <button className="ql-list" value="ordered"></button>
                <button className="ql-header" value="2"></button>
                <button className="ql-header" value="3"></button>
                <button className="ql-blockquote"></button>
                <button className="ql-list" value="bullet"></button>
                <button className="ql-indent" value="-1"></button>
                <button className="ql-indent" value="+1"></button>
            </span>
        );
    };

    const header = renderHeader();

    return (
        <>
            <Toast ref={toast}/>
            <table className="myTable">
                <thead className="myThead">
                <tr>
                    <th style={{width: 50}}></th>
                    <th style={{width: 250}}>{__('Data', 'gepafin')}</th>
                    <th style={{width: '100%'}}>{__('Comunicazione', 'gepafin')}</th>
                </tr>
                </thead>
                <tbody className="myTbody">
                {!isNil(comms) && !isEmpty(comms)
                    ? comms.map((o, i) => <tr key={o.id} className={getCommRowClass(o)}>
                        <td valign="top">
                            {displayCommIcon(o)}
                        </td>
                        <td valign="top">
                            {getDateFromISOstring(o.commentedDate)}
                        </td>
                        <td>
                            <h3>{o.title}</h3>
                            {renderHtmlContent(o.comment)}
                            {o.documents && !isEmpty(o.documents)
                                ? <div>{o.documents.map((doc) => <a href={doc.filePath} target="_blank" rel="noreferrer">{doc.name}</a>)}</div>
                                : null }
                        </td>
                    </tr>)
                    : <tr>
                        <td></td>
                        <td>-</td>
                        <td>-</td>
                    </tr>}
                </tbody>
            </table>

            <Button
                style={{marginTop: 30}}
                onClick={openNewCommDialog}
                disabled={soccorsoStatus === 'CLOSE'}
                type="button"
                label={__('Aggiungi Comunicazione', 'gepafin')}
                icon="pi pi-plus" iconPos="right"/>

            <Dialog
                visible={isVisibleNewCommDialog}
                modal
                header={headerNewComDialog}
                footer={footerNewComDialog}
                style={{maxWidth: '600px', width: '100%'}}
                onHide={hideNewComDialog}>
                <div className="appForm__field">
                    <label
                        className={classNames({'p-error': !newCommData.title || isEmpty(newCommData.title)})}>
                        {__('Titolo', 'gepafin')}*
                    </label>
                    <InputText value={newCommData.title}
                               disabled={soccorsoStatus === 'CLOSE'}
                               invalid={isEmpty(newCommData.title)}
                               onChange={(e) => updateNewCommData(e.target.value, 'title')}/>

                    <label
                        className={classNames({'p-error': !newCommData.comment || isEmpty(newCommData.comment)})}>
                        {__('Contenuto', 'gepafin')}*
                    </label>
                    <Editor
                        value={newCommData.comment}
                        placeholder={__('Digita qui il messagio', 'gepafin')}
                        readOnly={soccorsoStatus === 'CLOSE'}
                        headerTemplate={header}
                        onTextChange={(e) => updateNewCommData(e.htmlValue, 'comment')}
                        style={{ height: 80 * 3, width: '100%' }}
                    />
                    {!['ROLE_CONFIDI', 'ROLE_BENEFICIARY'].includes(role)
                        ? <div className="appForm__field">
                            <label>
                                {__('Files', 'gepafin')}
                            </label>
                            <FileUpload
                                ref={commDialogFilesRef}
                                name="files[]"
                                multiple
                                accept={mimeTypes.map(o => o.code).join(',')}
                                maxFileSize={defaultMaxFileSize}
                                auto={false}
                                customUpload={true}
                                onSelect={(e) => {
                                    updateNewCommData(e.files, 'files');
                                }}
                                onRemove={(e) => {
                                    const updatedFiles = commDialogFilesRef.current.getFiles();
                                    updateNewCommData(updatedFiles, 'files');
                                }}
                                headerTemplate={(options) => {
                                    const { chooseButton } = options;
                                    return (
                                        <div className="p-fileupload-buttonbar" data-pc-section="buttonbar">
                                            {chooseButton}
                                        </div>
                                    );
                                }}
                                chooseOptions={{
                                    label: __('Aggiungi i file', 'gepafin'),
                                    icon: 'pi pi-plus'
                                }}
                                itemTemplate={(file, props) => {
                                    return(
                                        <div className="p-fileupload-row" data-pc-section="file">
                                            <div data-pc-section="details" style={{display: 'flex', flexDirection: 'column', gap: '10px', textAlign: 'left'}}>
                                                <div className="p-fileupload-filename" data-pc-section="filename">
                                                    {file.name}
                                                </div>
                                                <span data-pc-section="filesize">{getFormatedFileSizeText(file.size)}</span>
                                            </div>
                                            <div data-pc-section="actions">
                                                <Button
                                                    type="button"
                                                    icon="pi pi-times"
                                                    className="p-button-rounded p-button-danger p-button-text"
                                                    onClick={() => props.onRemove()}
                                                />
                                            </div>
                                        </div>
                                    )
                                }}
                                emptyTemplate={<p className="m-0">{__('Trascina i file qua')}</p>}
                            />
                        </div> : null}
                </div>
            </Dialog>
        </>
    );
};

export default SoccorsoComunications;