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

// api
import PecEmailService from '../../../../service/pec-email-service';

// tools
import renderHtmlContent from '../../../../helpers/renderHtmlContent';

// components
import { FilterMatchMode, FilterOperator } from 'primereact/api';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Button } from 'primereact/button';
import { Toast } from 'primereact/toast';
import { Dialog } from 'primereact/dialog';
import { Editor } from 'primereact/editor';

import translationStrings from '../../../../translationStringsForComponents';
import { autorizationNames } from '../../../../configData';

const LatestPecEmailsTable = () => {
    const [items, setItems] = useState(null);
    const [filters, setFilters] = useState(null);
    const [selectedProducts, setSelectedProducts] = useState(null);
    const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
    const [isVisibleDetails, setIsVisibleDetails] = useState(false);
    const [previewItem, setPreviewItem] = useState({});
    const [isVisibleRejectDialog, setIsVisibleRejectDialog] = useState(false);
    const [rejectMotivation, setRejectMotivation] = useState('N/D');
    const [pendingRejectIds, setPendingRejectIds] = useState([]);
    const toast = useRef(null);

    useEffect(() => {
        setLocalAsyncRequest(true);
        PecEmailService.getPecEmails(getCallback, errGetCallbacks);
    }, []);

    const getCallback = (data) => {
        if (data.status === 'SUCCESS') {
            setItems(data.data);
        }
        setLocalAsyncRequest(false);
    }

    const errGetCallbacks = () => {
        setLocalAsyncRequest(false);
    }

    const clearFilter = () => {
        initFilters();
    };

    const initFilters = () => {
        setFilters({
            global: { value: null, matchMode: FilterMatchMode.CONTAINS },
            name: {
                operator: FilterOperator.AND,
                constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
            },
            start_date: {
                operator: FilterOperator.AND,
                constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
            },
            end_date: {
                operator: FilterOperator.AND,
                constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
            },
            status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }
        });
    };

    const doAccept = (ids) => {
        if (isEmpty(ids)) {
            return;
        }
        setLocalAsyncRequest(true);
        PecEmailService.doUserAction(getUserActionCallback, errGetUserActionCallbacks, [
            ['userActionIds', ids]
        ]);
    }

    const getUserActionCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            if (toast.current && resp.message) {
                toast.current.show({
                    severity: 'success',
                    summary: '',
                    detail: resp.message
                });
            }
            PecEmailService.getPecEmails(getCallback, errGetCallbacks);
        } else {
            setLocalAsyncRequest(false);
        }
    }

    const errGetUserActionCallbacks = (resp) => {
        setLocalAsyncRequest(false);
        if (toast.current && resp.message) {
            toast.current.show({
                severity: resp.status === 'SUCCESS' ? 'info' : 'error',
                summary: '',
                detail: resp.message
            });
        }
    }

    const openRejectDialog = (ids) => {
        if (isEmpty(ids)) return;
        setPendingRejectIds(ids);
        setIsVisibleRejectDialog(true);
    };

    const hideRejectDialog = () => {
        setIsVisibleRejectDialog(false);
        setRejectMotivation('N/D');
        setPendingRejectIds([]);
    };

    const doReject = () => {
        if (isEmpty(pendingRejectIds)) return;
        setLocalAsyncRequest(true);
        setIsVisibleRejectDialog(false);
        for (let id of pendingRejectIds) {
            PecEmailService.rejectUserAction(id, getUserRejectActionCallback, errGetUserRejectActionCallbacks,
                [['motivation', rejectMotivation]]
            );
        }
        setRejectMotivation('N/D');
        setPendingRejectIds([]);
    }

    const getUserRejectActionCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            if (toast.current && resp.message) {
                toast.current.show({
                    severity: 'success',
                    summary: '',
                    detail: resp.message
                });
            }
            PecEmailService.getPecEmails(getCallback, errGetCallbacks);
        } else {
            setLocalAsyncRequest(false);
        }
    }

    const errGetUserRejectActionCallbacks = (resp) => {
        setLocalAsyncRequest(false);
        if (toast.current && resp.message) {
            toast.current.show({
                severity: resp.status === 'SUCCESS' ? 'info' : 'error',
                summary: '',
                detail: resp.message
            });
        }
    }

    const doShowDetails = (row) => {
        setPreviewItem(row);
        setIsVisibleDetails(true);
    }

    const headerDialog = () => {
        return <span>{__('I dettagli dell\'email', 'gepafin')}</span>;
    }

    const hideDialog = () => {
        setIsVisibleDetails(false);
        setPreviewItem({});
    }

    const headerRejectDialog = () => <span>{__('Confermare il rifiuto', 'gepafin')}</span>;

    const footerRejectDialog = useCallback(() => (
        <div>
            <Button type="button" label={__('Annulla', 'gepafin')} onClick={hideRejectDialog} outlined/>
            <Button type="button" disabled={localAsyncRequest}
                label={__('Invia', 'gepafin')} onClick={doReject} severity="danger"/>
        </div>
    ), [pendingRejectIds, rejectMotivation, localAsyncRequest]);

    const footerDialog = useCallback(() => {
        return <div>
            <Button type="button" label={__('Annulla', 'gepafin')} onClick={hideDialog} outlined/>
            {previewItem && !isEmpty(previewItem)
                ? <Button
                    type="button"
                    disabled={localAsyncRequest}
                    label={__('Accetta', 'gepafin')} onClick={() => doAccept([previewItem.userActionId])}/>
                : null}
        </div>
    }, [previewItem]);

    const renderHeader = useCallback(() => {
        return (
            <div className="appTableHeader">
                <Button type="button" icon="pi pi-filter-slash" label={__('Pulisci', 'gepafin')} outlined
                        onClick={clearFilter}/>
                {selectedProducts && !isEmpty(selectedProducts) && (
                    <Button type="button" icon="pi pi-check" label={__('Accetta tutte', 'gepafin')}
                            onClick={() => doAccept(pluck('userActionId', selectedProducts))}/>
                )}
            </div>
        );
    }, [selectedProducts]);

    const typeBodyTemplate = (rowData) => {
        return !isNil(autorizationNames[rowData.type]) ? autorizationNames[rowData.type] : rowData.type;
    }

    const actionsBodyTemplate = (rowData) => {
        return <div className="appPageSection__tableActions lessGap">
            <Button severity="info"
                    onClick={() => doShowDetails(rowData)}
                    label={__('Dettagli', 'gepafin')}
                    icon="pi pi-eye"
                    size="small"
                    iconPos="right"/>
            <Button severity="success"
                    onClick={() => doAccept([rowData.userActionId])}
                    label={__('Accetta', 'gepafin')}
                    icon="pi pi-check"
                    size="small"
                    iconPos="right"/>
            <Button severity="danger"
                    onClick={() => openRejectDialog([rowData.userActionId])}
                    label={__('Rifiuta', 'gepafin')}
                    icon="pi pi-times"
                    size="small"
                    iconPos="right"/>
        </div>
    }

    const header = renderHeader();

    const renderHeaderEditor = () => {
        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 headerEditor = renderHeaderEditor();

    return <div className="appPageSection__table">
        <DataTable value={items}
                   paginator showGridlines
                   rows={5} loading={localAsyncRequest} dataKey="id"
                   filters={filters} stripedRows removableSort
                   header={header}
                   emptyMessage={translationStrings.emptyMessage}
                   selectionMode="checkbox"
                   selection={selectedProducts}
                   onSelectionChange={(e) => setSelectedProducts(e.value)}
                   onFilter={(e) => setFilters(e.filters)}>
            <Column selectionMode="multiple" headerStyle={{ width: '3rem' }}></Column>
            <Column field="id" header={__('ID', 'gepafin')}
                    filter sortable
                    filterPlaceholder={__('Cerca', 'gepafin')}
                    style={{ minWidth: '3rem' }}/>
            <Column field="callName" header={__('Nome Bando', 'gepafin')}
                    filter sortable
                    filterPlaceholder={__('Cerca il nome', 'gepafin')}
                    style={{ minWidth: '8rem' }}/>
            <Column field="applicationId" header={__('Domanda ID', 'gepafin')}
                    filter sortable
                    filterPlaceholder={__('Cerca ID', 'gepafin')}
                    style={{ minWidth: '8rem' }}/>
            <Column header={__('Tipo', 'gepafin')}
                    body={typeBodyTemplate}
                    style={{ minWidth: '8rem' }}/>
            <Column header={__('Azioni', 'gepafin')}
                    body={actionsBodyTemplate}/>
        </DataTable>

        <Toast ref={toast}/>

        <Dialog
            visible={isVisibleDetails}
            modal
            header={headerDialog}
            footer={footerDialog}
            style={{ maxWidth: '600px', width: '100%' }}
            onHide={hideDialog}>
            <div className="appForm__field">
                <h2>{__('Tipo:', 'gepafin')}</h2>
                <div>
                    <code>{!isNil(autorizationNames[previewItem.type]) ? autorizationNames[previewItem.type] : previewItem.type}</code>
                </div>
                <h2>{__('Oggetto:', 'gepafin')}</h2>
                <div>
                    {renderHtmlContent(previewItem.subject)}
                </div>
                <h2>{__('Il corpo:', 'gepafin')}</h2>
                <div>
                    {renderHtmlContent(previewItem.htmlContent)}
                </div>
            </div>
        </Dialog>

        <Dialog
            visible={isVisibleRejectDialog}
            modal
            header={headerRejectDialog}
            footer={footerRejectDialog}
            style={{ maxWidth: '600px', width: '100%' }}
            onHide={hideRejectDialog}>
            <div className="appForm__field">
                <label>{__('Motivazione', 'gepafin')} *</label>
                <div translate="no">
                    <Editor
                        value={rejectMotivation}
                        readOnly={localAsyncRequest}
                        headerTemplate={headerEditor}
                        onTextChange={(e) => setRejectMotivation(e.htmlValue)}
                        style={{ height: 80 * 3, width: '100%' }}
                    />
                </div>
            </div>
        </Dialog>
    </div>
}

export default LatestPecEmailsTable;