import {useLoadingSwitcher} from "../../../hooks/useLoading.jsx";
import {useFetch} from "../../../hooks/useFetch.js";
import {useEffect, useReducer, useState} from "react";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faEuroSign, faPen} from "@fortawesome/free-solid-svg-icons";
import {AxiosError} from "../../../components/AxiosError.jsx";
import {apiAxios, getSaison, getToastMessage} from "../../../utils/Tools.js";
import {toast} from "react-toastify";
import {useTranslation} from "react-i18next";

function licenceReducer(licences, action) {
    switch (action.type) {
        case 'ADD':
            return [
                ...licences,
                action.payload
            ]
        case 'REMOVE':
            return licences.filter(licence => licence.id !== action.payload)
        case 'UPDATE_OR_ADD':
            const index = licences.findIndex(licence => licence.id === action.payload.id)
            if (index === -1) {
                return [
                    ...licences,
                    action.payload
                ]
            } else {
                licences[index] = action.payload
                return [...licences]
            }
        case 'SORT':
            return licences.sort((a, b) => b.saison - a.saison)
        default:
            throw new Error()
    }
}

export function LicenceCard({userData}) {
    const setLoading = useLoadingSwitcher()
    const {data, error} = useFetch(`/licence/${userData.id}`, setLoading, 1)
    const {t} = useTranslation();

    const [modalLicence, setModal] = useState({id: -1, membre: userData.id})
    const [licences, dispatch] = useReducer(licenceReducer, [])

    useEffect(() => {
        if (!data) return
        for (const dataKey of data) {
            dispatch({type: 'UPDATE_OR_ADD', payload: dataKey})
        }
        dispatch({type: 'SORT'})
    }, [data]);

    return <div className="card mb-4 mb-md-0">
        <div className="card-header container-fluid">
            <div className="row">
                <div className="col">{t('licence')}</div>
                <div className="col" style={{textAlign: 'right'}}>
                    <button className="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#LicenceModal"
                            onClick={_ => setModal({id: -1, membre: userData.id})}>{t('button.ajouter')}
                    </button>
                </div>
            </div>
        </div>
        <div className="card-body">
            <ul className="list-group">
                {licences.map((licence, index) => {
                    return <div key={index}
                                className={"list-group-item d-flex justify-content-between align-items-start list-group-item-" +
                                    (licence.validate ? "success" : (licence.certificate?.length > 1 ? "warning" : "danger"))}>
                        <div className="me-auto">{licence?.saison}-{licence?.saison + 1}  {(licence.pay) && <FontAwesomeIcon icon={faEuroSign}/>}</div>
                        <button className="badge btn btn-primary rounded-pill" data-bs-toggle="modal"
                                data-bs-target="#LicenceModal" onClick={_ => setModal(licence)}>
                            <FontAwesomeIcon icon={faPen}/></button>
                    </div>
                })}
                {error && <AxiosError error={error}/>}
            </ul>
        </div>

        <div className="modal fade" id="LicenceModal" tabIndex="-1" aria-labelledby="LicenceModalLabel"
             aria-hidden="true">
            <div className="modal-dialog">
                <div className="modal-content">
                    <ModalContent licence={modalLicence} dispatch={dispatch}/>
                </div>
            </div>
        </div>
    </div>;
}

function sendLicence(event, dispatch) {
    event.preventDefault();

    const formData = new FormData(event.target);
    formData.set('licence', event.target.licence?.value?.length > 0 ? event.target.licence?.value : null)
    formData.set('certificate', `${event.target.certificateBy?.value}¤${event.target.certificateDate?.value}`)

    toast.promise(
        apiAxios.post(`/licence/${formData.get('membre')}`, formData), getToastMessage("membre.toast.licence.save")
    ).then(data => {
        dispatch({type: 'UPDATE_OR_ADD', payload: data.data})
        dispatch({type: 'SORT'})
    })

}

function removeLicence(id, dispatch) {
    toast.promise(
        apiAxios.delete(`/licence/${id}`), getToastMessage("membre.toast.licence.del")
    ).then(_ => {
        dispatch({type: 'REMOVE', payload: id})
    })
}

function ModalContent({licence, dispatch}) {
    const [saison, setSaison] = useState(0)
    const [certificateBy, setCertificateBy] = useState("")
    const [certificateDate, setCertificateDate] = useState("")
    const [validate, setValidate] = useState(false)
    const [pay, setPay] = useState(false)
    const [isNew, setNew] = useState(true)
    const {t} = useTranslation();
    const setSeason = (event) => {
        setSaison(Number(event.target.value))
    }
    const handleCertificateByChange = (event) => {
        setCertificateBy(event.target.value.replaceAll('¤', ''));
    }
    const handleCertificateDateChange = (event) => {
        setCertificateDate(event.target.value.replaceAll('¤', ''));
    }
    const handleValidateChange = (event) => {
        setValidate(event.target.value === 'true');
    }
    const handlePayChange = (event) => {
        setPay(event.target.value === 'true');
    }

    useEffect(() => {
        if (licence.id !== -1) {
            setNew(false)
            setSaison(licence.saison)
            if (licence.certificate === null) {
                setCertificateBy("")
                setCertificateDate("")
            } else {
                setCertificateBy(licence.certificate.split('¤')[0])
                setCertificateDate(licence.certificate.split('¤')[1])
            }
            setValidate(licence.validate)
            setPay(licence.pay);
        } else {
            setNew(true)
            setSaison(getSaison())
            setCertificateBy("")
            setCertificateDate("")
            setValidate(false)
            setPay(false);
        }
    }, [licence]);

    return <form onSubmit={e => sendLicence(e, dispatch)}>
        <input name="id" value={licence.id} readOnly hidden/>
        <input name="membre" value={licence.membre} readOnly hidden/>
        <div className="modal-header">
            <h1 className="modal-title fs-5" id="LicenceModalLabel">{t('editionDeLaLicence')}</h1>
            <button type="button" className="btn-close" data-bs-dismiss="modal"
                    aria-label="Close"></button>
        </div>
        <div className="modal-body">
            <div className="input-group mb-3  justify-content-md-center">
                {isNew
                    ? <input type="number" className="form-control" placeholder="Saison" name="saison"
                             aria-label="Saison" aria-describedby="basic-addon2" value={saison} onChange={setSeason}/>
                    : <><span className="input-group-text" id="basic-addon2">{saison}</span>
                        <input name="saison" value={saison} readOnly hidden/></>}
                <span className="input-group-text" id="basic-addon2">-</span>
                <span className="input-group-text" id="basic-addon2">{saison + 1}</span>
            </div>

            <span>{t('certificatMédical')}</span>
            <div className="input-group mb-3 ">
                <span className="input-group-text" id="basic-addon2">{t('faitPar')}</span>
                <input type="text" className="form-control" placeholder={t('faitPar')} name="certificateBy"
                       aria-label={t('faitPar')} aria-describedby="basic-addon2" value={certificateBy} onChange={handleCertificateByChange}/>
                <span className="input-group-text" id="basic-addon2">, {t('le')}</span>
                <input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate"
                       aria-describedby="basic-addon2" value={certificateDate} onChange={handleCertificateDateChange}/>
            </div>
            <RadioGroupeOnOff name="pay" text={t('paiementDeLaLicence')} value={pay}
                              onChange={handlePayChange}/>
            <RadioGroupeOnOff name="validate" text={t('validationDeLaLicence')} value={validate}
                              onChange={handleValidateChange}/>
        </div>
        <div className="modal-footer">
            <button type="submit" className="btn btn-primary" data-bs-dismiss="modal">{t('button.enregistrer')}</button>
            <button type="reset" className="btn btn-secondary" data-bs-dismiss="modal">{t('button.annuler')}</button>
            {isNew || <button type="button" className="btn btn-danger" data-bs-dismiss="modal"
                              onClick={() => removeLicence(licence.id, dispatch)}>{t('button.supprimer')}</button>}
        </div>
    </form>
}

function RadioGroupeOnOff({value, onChange, name, text}) {
    return <div className="btn-group input-group mb-3 justify-content-md-center" role="group"
                aria-label="Basic radio toggle button group">
        <span className="input-group-text">{text}</span>
        <input type="radio" className="btn-check" id={"btnradio1" + name} autoComplete="off"
               value="false" checked={value === false} onChange={onChange}/>
        <label className="btn btn-outline-primary" htmlFor={"btnradio1" + name}>Non</label>
        <input type="radio" className="btn-check" name={name} id={"btnradio2" + name} autoComplete="off"
               value="true" checked={value === true} onChange={onChange}/>
        <label className="btn btn-outline-primary" htmlFor={"btnradio2" + name}>Oui</label>
    </div>;
}
