import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { __ } from '@wordpress/i18n';
import { useNavigate, useParams } from 'react-router-dom';
import { klona } from 'klona';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

// api
import EvaluationFormsService from '../../../../service/evaluation-forms-service';
import FormsService from '../../../../service/forms-service';

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

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

// components
import BandoEditFormActions from '../BandoEditFormActions';
import { Toast } from 'primereact/toast';
import FormBuilder from '../../../BandoFormsEdit/components/FormBuilder';
//import { elementItems } from '../../../../tempData';


const BandoEditFormStep3 = forwardRef(function () {
    const navigate = useNavigate();
    const { id } = useParams();
    const [formName, setFormName] = useState('');
    const [bandoStatus, setBandoStatus] = useState('');
    const toast = useRef(null);

    const getBandoId = () => {
        const parsed = parseInt(id)
        return !isNaN(parsed) ? parsed : 0;
    }

    const onSaveDraft = () => {
        const content = storeGet('formElements');
        const formId = storeGet('formId');
        const formData = {
            label: formName,
            content
        }

        storeSet('setAsyncRequest');
        EvaluationFormsService.updateForm(formId, formData, updateFormCallback, errUpdateFormCallback)
    }

    const updateFormCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            setBandoStatus(resp.data.callStatus);
            if (toast.current) {
                toast.current.show({
                    severity: 'success',
                    summary: '',
                    detail: __('Il bando è stato aggiornato correttamente!', 'gepafin')
                });
            }
        }
        storeSet('unsetAsyncRequest');
    }

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

    const openPreview = () => {
        const bandoId = getBandoId();
        navigate(`/bandi/${bandoId}/preview`);
    }

    const openPreviewEvaluation = () => {
        const bandoId = getBandoId();
        navigate(`/bandi/${bandoId}/preview-evaluation`);
    }

    const getElementItemsCallback = (data) => {
        if (data.status === 'SUCCESS') {
            //storeSet('elementItems', elementItems.sort((a, b) => a.sortOrder - b.sortOrder));
            storeSet(
                'elementItems',
                data.data
                    .filter(o => !['fileselect'].includes(o.name))
                    .sort((a, b) => a.sortOrder - b.sortOrder)
            );
        }
        storeSet('unsetAsyncRequest');
    }

    const errGetElementItemsCallbacks = (data) => {
        storeSet('unsetAsyncRequest');
    }

    const getFormsCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            const EXCLUDED_TYPES = new Set(['fileupload', 'fileselect', 'spreadsheet']);
            const raw = (resp.data ?? []).flatMap(form =>
                (form.content ?? [])
                    .filter(f => !EXCLUDED_TYPES.has(f.name))
                    .map(f => ({
                        id: f.id,
                        label: f.settings?.find(s => s.name === 'label')?.value ?? f.label,
                        placeholder: f.settings?.find(s => s.name === 'placeholder')?.value ?? ''
                    }))
            );
            const byLabel = new Map();
            raw.forEach(f => {
                if (!byLabel.has(f.label)) byLabel.set(f.label, { label: f.label, ids: [], placeholder: f.placeholder });
                byLabel.get(f.label).ids.push(f.id);
            });
            storeSet('callFormFields', Array.from(byLabel.values()));
        }
    }

    const errGetFormsCallback = () => {}

    const getFormCallback = (resp) => {
        if (resp.status === 'SUCCESS') {
            storeSet('formId', resp.data.id);
            storeSet('formLabel', resp.data.label);
            setFormName(resp.data.label);
            setBandoStatus(resp.data.callStatus);
            const elements = klona(resp.data.content);
            storeSet('formElements', elements);
        }
        storeSet('unsetAsyncRequest');
    }

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

    useEffect(() => {
        storeSet('setAsyncRequest');
        EvaluationFormsService.getFormForCall(id, getFormCallback, errGetFormCallback)
    }, [id]);

    useEffect(() => {
        storeSet('setAsyncRequest');
        FormsService.getElementItems(getElementItemsCallback, errGetElementItemsCallbacks);
        FormsService.getFormsForCall(id, getFormsCallback, errGetFormsCallback);

        return () => {
            storeSet('formId', 0);
            storeSet('formElements', []);
            storeSet('activeElement', '');
            storeSet('selectedElement', '');
            storeSet('callFormFields', []);
        }
    }, []);

    return (
        <div className="appForm">
            <div className="appPageSection">
                <DndProvider backend={HTML5Backend}>
                    <FormBuilder callStatus={bandoStatus} context="call"/>
                </DndProvider>
            </div>

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

            <div className="appPageSection__hr">
                <span>{__('Azioni', 'gepafin')}</span>
            </div>

            <Toast ref={toast} />
            <BandoEditFormActions
                id={id}
                status={bandoStatus}
                submitFn={onSaveDraft}
                openPreview={openPreview}
                openPreviewEvaluation={openPreviewEvaluation}/>
        </div>
    )
})

export default BandoEditFormStep3;