import React, { useState, useEffect, useRef } from 'react';
import { __ } from '@wordpress/i18n';
import { useNavigate, useParams } from 'react-router-dom';
import { is, isNil, isEmpty, pathOr } from 'ramda';

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

// api
import BandoService from '../../service/bando-service';
import FormsService from '../../service/forms-service';

// tools
import getBandoLabel from '../../helpers/getBandoLabel';
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';

// components
import { Button } from 'primereact/button';
import { Skeleton } from 'primereact/skeleton';
import { Steps } from 'primereact/steps';
import BandoEditFormStep1 from './components/BandoEditFormStep1';
import BandoEditFormStep2 from './components/BandoEditFormStep2';
import { Messages } from 'primereact/messages';
import BlockingOverlay from '../../components/BlockingOverlay';
import { Toast } from 'primereact/toast';
import { ConfirmPopup, confirmPopup } from 'primereact/confirmpopup';
import BandoEditFormStep3 from './components/BandoEditFormStep3';

const BandoEdit = () => {
    const isAsyncRequest = useStoreValue('isAsyncRequest');
    const navigate = useNavigate();
    const { id } = useParams();
    const [activeStep, setActiveStep] = useState(null)
    const [data, setData] = useState({});
    const [forms, setForms] = useState([]);
    const formRef = useRef(null);
    const bandoMsgs = useRef(null);
    const toast = useRef(null);

    const stepItems = (evalProcessVer) => {
        let steps = [
            {
                label: __('Testi', 'gepafin'),
                command: () => {
                    if (activeStep === 0) {
                        return false
                    }
                    bandoMsgs.current.clear();
                    goToStep(0);
                }
            },
            {
                label: __('Gestione', 'gepafin'),
                command: () => {
                    if (activeStep === 1) {
                        return false
                    }
                    bandoMsgs.current.clear();
                    goToStep(1);
                }
            }
        ];

        if (evalProcessVer === 'V2') {
            steps.push({
                label: __('Valutazione', 'gepafin'),
                command: () => {
                    if (activeStep === 2) {
                        return false
                    }
                    bandoMsgs.current.clear();
                    goToStep(2);
                }
            })
        }

        return steps;
    }

    const goToStep = (step) => {
        setActiveStep(step);
    }

    const openBandoFormManagement = () => {
        navigate(`/bandi/${id}/forms`);
    }

    const openBandoFlowManagement = () => {
        navigate(`/bandi/${id}/flow`);
    }

    const openRendicontazioneSchema = () => {
        navigate(`/bandi/${id}/rendicontazione-schema`);
    }

    const validateBando = () => {
        storeSet('setAsyncRequest');
        bandoMsgs.current.clear();
        BandoService.validateBando(id, validateCallback, errValidateCallback);
    }

    const validateCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            setData(resp.data);
            if (bandoMsgs.current) {
                bandoMsgs.current.show([
                    {
                        id: '99',
                        sticky: true, severity: 'info', summary: '',
                        detail: __('Potrai pubblicare il tuo Bando.', 'gepafin'),
                        closable: false
                    }
                ]);
                if (toast.current) {
                    toast.current.show({
                        severity: 'info',
                        summary: '',
                        detail: __('Potrai pubblicare il tuo Bando.', 'gepafin')
                    });
                }
            }
        }
        storeSet('unsetAsyncRequest');
    }

    const errValidateCallback = (resp) => {
        if (resp.status === 'VALIDATION_ERROR') {
            storeSet('unsetAsyncRequest');
            if (bandoMsgs.current) {
                bandoMsgs.current.show(resp.data.map((v, i) => ({
                    id: i,
                    sticky: true, severity: 'error', summary: '',
                    detail: v,
                    closable: false
                })));
            }
            if (toast.current) {
                toast.current.show(resp.data.map((v, i) => ({
                    severity: 'error',
                    summary: '',
                    detail: v
                })));
            }
        } else {
            standardErrCallback(resp);
        }
    }

    const publishBando = () => {
        storeSet('setAsyncRequest');
        bandoMsgs.current.clear();
        BandoService.updateBandoStatus(id, publishCallback, errPublishCallback, [['status', 'PUBLISH']]);
    }

    const publishCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            if (bandoMsgs.current) {
                bandoMsgs.current.show([
                    {
                        id: '99',
                        sticky: true, severity: 'success', summary: '',
                        detail: __('Pubblicato!', 'gepafin'),
                        closable: false
                    }
                ]);
            }
            if (toast.current) {
                toast.current.show({
                    severity: 'success',
                    summary: '',
                    detail: __('Pubblicato!', 'gepafin')
                });
            }
            if (resp.data.docs) {
                resp.data.docs = resp.data.docs
                    .filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
            }
            setData(resp.data);
        }
        storeSet('unsetAsyncRequest');
    }

    const errPublishCallback = (resp) => {
        standardErrCallback(resp);
    }

    const getCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            if (!isNil(resp.data.dates) && resp.data.dates.length) {
                if (resp.data.dates[0]) {
                    resp.data.startDate = is(String, resp.data.dates[0]) ? new Date(resp.data.dates[0]) : (resp.data.dates[0] ? resp.data.dates[0] : '');
                }
                if (resp.data.dates[1]) {
                    resp.data.endDate = is(String, resp.data.dates[1]) ? new Date(resp.data.dates[1]) : (resp.data.dates[1] ? resp.data.dates[1] : '');
                }
            }

            if (resp.data.status === 'READY_TO_PUBLISH') {
                bandoMsgs.current.clear();
                bandoMsgs.current.show([
                    {
                        id: '1',
                        sticky: true, severity: 'info', summary: '',
                        detail: __('Potrai pubblicare il tuo Bando.', 'gepafin'),
                        closable: false
                    }
                ]);
            } else if (resp.data.status === 'DRAFT') {
                if (bandoMsgs.current) {
                    bandoMsgs.current.clear();
                    bandoMsgs.current.show([
                        {
                            id: '1',
                            sticky: true, severity: 'info', summary: '',
                            detail: __('Potrai pubblicare il tuo Bando solo dopo aver completato tutti i campi obbligatori contrassegnati dagli asterischi.', 'gepafin'),
                            closable: false
                        }
                    ]);
                }
            }
            if (resp.data.docs) {
                resp.data.docs = resp.data.docs
                    .filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
            }
            setData(resp.data);
        }
        storeSet('unsetAsyncRequest');
    }

    const errGetCallback = (resp) => {
        set404FromErrorResponse(resp);
        storeSet('unsetAsyncRequest');
    }

    const standardErrCallback = (resp) => {
        if (bandoMsgs.current && resp.message) {
            bandoMsgs.current.show([
                {
                    sticky: true, severity: 'error', summary: '',
                    detail: resp.message,
                    closable: true
                }
            ]);
        }
        storeSet('unsetAsyncRequest');
    }

    const getFormsCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            setForms(resp.data);
        }
        storeSet('unsetAsyncRequest');
    }

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

    const unpublishBando = () => {
        storeSet('setAsyncRequest');
        bandoMsgs.current.clear();
        BandoService.updateBandoStatus(id, unpublishCallback, errUnpublishCallback, [['status', 'DRAFT']]);
    }

    const unpublishCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            if (bandoMsgs.current) {
                bandoMsgs.current.show([
                    {
                        id: '99',
                        sticky: true, severity: 'success', summary: '',
                        detail: __('Stato cambiato!', 'gepafin'),
                        closable: false
                    }
                ]);
            }
            if (toast.current) {
                toast.current.show({
                    severity: 'success',
                    summary: '',
                    detail: __('Stato cambiato!', 'gepafin')
                });
            }
            if (resp.data.docs) {
                resp.data.docs = resp.data.docs
                    .filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
            }
            setData(resp.data);
        }
        storeSet('unsetAsyncRequest');
    }

    const errUnpublishCallback = (resp) => {
        const message = pathOr('', ['message'], resp);
        if (message && toast.current) {
            toast.current.show({
                severity: 'error',
                summary: message,
                detail: ''
            });
        }
        standardErrCallback(resp);
    }

    useEffect(() => {
        storeSet('setAsyncRequest');
        setActiveStep(0);

        const parsed = parseInt(id)
        const bandoId = !isNaN(parsed) ? parsed : 0;

        if (bandoId === 0) {
            setData({
                status: null,
                evaluationVersion: 'V2'
            });
            storeSet('unsetAsyncRequest');

            if (bandoMsgs.current) {
                bandoMsgs.current.clear();
                bandoMsgs.current.show([
                    {
                        id: '1',
                        sticky: true, severity: 'info', summary: '',
                        detail: __('Potrai pubblicare il tuo Bando solo dopo aver completato tutti i campi obbligatori contrassegnati dagli asterischi.', 'gepafin'),
                        closable: false
                    }
                ]);
            }
        } else {
            BandoService.getBando(id, getCallback, errGetCallback);
            FormsService.getFormsForCall(id, getFormsCallback, () => {
            });
        }
    }, [id]);

    return (
        <div className="appPage">
            <div className="appPage__pageHeader">
                <h1>{__('Creazione/Modifica Bando', 'gepafin')}</h1>
                <p>
                    {__('Stato:', 'gepafin')}
                    <span>{getBandoLabel(data.status)}</span>
                </p>
            </div>

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

            {!isEmpty(data)
                ? <Steps
                    model={stepItems(data.evaluationVersion)}
                    activeIndex={activeStep}
                    readOnly={isNil(data.status)}/>
                : null}
            <BlockingOverlay shouldDisplay={isAsyncRequest}/>

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

            <Messages ref={bandoMsgs}/>
            <Toast ref={toast}/>

            {!isEmpty(data)
                ? <>
                    {activeStep === 0
                        ? <BandoEditFormStep1 initialData={data} setInitialData={setData} ref={formRef}
                                              status={data.status}/>
                        : null}
                    {activeStep === 1
                        ? <BandoEditFormStep2 initialData={data} setInitialData={setData} ref={formRef}
                                              status={data.status}/>
                        : null}
                    {activeStep === 2 && data.evaluationVersion === 'V2'
                        ? <BandoEditFormStep3/>
                        : null}

                    <div className="appPageSection">
                        <h2>{__('Crea o modifica il Form compilabile dal Beneficiario', 'gepafin')}</h2>

                        <div className="row">
                            <Button
                                type="button"
                                outlined={data.status === 'PUBLISH'}
                                onClick={openBandoFormManagement}
                                label={__('Crea/modifica form', 'gepafin')}/>

                            <Button
                                type="button"
                                disabled={!['DRAFT', 'PUBLISH', 'READY_TO_PUBLISH'].includes(data.status)}
                                outlined={data.status === 'PUBLISH'}
                                onClick={openBandoFlowManagement}
                                icon="pi pi-sitemap"
                                iconPos="right"
                                label={__('Gestisci flusso dei form', 'gepafin')}/>
                        </div>

                        {forms.length
                            ? <ul className="">
                                {forms.map(o => <li key={o.id}>
                                    {o.label}
                                </li>)}
                            </ul>
                            : <p>{__('Nessun modulo creato ancora', 'gepafin')}</p>}
                    </div>

                    <div className="appPageSection">
                        <h2>{__('Schema di rendicontazione', 'gepafin')}</h2>
                        <p className="text-color-secondary">
                            {__('Configura come i beneficiari dovranno rendicontare dopo la firma del contratto: categorie di spesa, ULA, documenti richiesti.', 'gepafin')}
                        </p>
                        <div className="row">
                            <Button
                                type="button"
                                outlined={data.status === 'PUBLISH'}
                                onClick={openRendicontazioneSchema}
                                icon="pi pi-receipt"
                                iconPos="right"
                                label={__('Crea o modifica schema di rendicontazione', 'gepafin')}/>
                        </div>
                    </div>

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

                    <div className="appPageSection">
                        <h2>{__('Pubblica il form', 'gepafin')}</h2>

                        <div className="row">
                            <Button
                                type="button"
                                outlined
                                disabled={!(data.status === 'DRAFT')}
                                onClick={validateBando}
                                label={__('Validate', 'gepafin')}/>
                            <Button
                                type="button"
                                disabled={!(data.status === 'READY_TO_PUBLISH')}
                                onClick={publishBando}
                                label={__('Publish', 'gepafin')}/>
                            {'PUBLISH' === data.status
                                ? <>
                                    <ConfirmPopup/>
                                    <Button
                                        onClick={confirmDelete}
                                        disabled={isAsyncRequest}
                                        severity="warning"
                                        label={__('Mettere in bozza', 'gepafin')}/></> : null}
                        </div>
                    </div>
                </>
                : <>
                    <Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
                    <Skeleton width="100%" height="2rem" className="mb-8"></Skeleton>
                    <Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
                    <Skeleton width="100%" height="4rem" className="mb-8"></Skeleton>
                    <Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
                    <Skeleton width="100%" height="2rem" className="mb-8"></Skeleton>
                    <Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
                    <Skeleton width="100%" height="4rem"></Skeleton>
                </>}
        </div>
    )
}

export default BandoEdit;