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, CatList, errFormater, getCatName, getSaison, getToastMessage} from "../../../utils/Tools.js";
import {toast} from "react-toastify";
import {useTranslation} from "react-i18next";

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

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

    const [modalSelection, setModal] = useState({id: -1, membre: userData.id})
    const [selections, dispatch] = useReducer(selectionReducer, [])

    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('sélectionEnéquipeDeFrance')}</div>
                <div className="col" style={{textAlign: 'right'}}>
                    <button className="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#SelectionModal"
                            onClick={() => setModal({id: -1, membre: userData.id, categorie: userData.categorie})}>{t('button.ajouter')}
                    </button>
                </div>
            </div>
        </div>
        <div className="card-body">
            <ul className="list-group">
                {selections.map((selection, index) => {
                    return <div key={index} className="list-group-item d-flex justify-content-between align-items-start">
                        <div className="me-auto">{selection?.saison}-{selection?.saison + 1} {t('en')} {getCatName(selection?.categorie)}</div>
                        <button className="badge btn btn-primary rounded-pill" data-bs-toggle="modal"
                                data-bs-target="#SelectionModal" onClick={_ => setModal(selection)}>
                            <FontAwesomeIcon icon={faPen}/></button>
                    </div>
                })}
                {error && <AxiosError error={error}/>}
            </ul>
        </div>

        <div className="modal fade" id="SelectionModal" tabIndex="-1" aria-labelledby="SelectionModalLabel"
             aria-hidden="true">
            <div className="modal-dialog">
                <div className="modal-content">
                    <ModalContent selection={modalSelection} dispatch={dispatch}/>
                </div>
            </div>
        </div>
    </div>;
}

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

    const formData = new FormData(event.target);
    formData.set('selection', event.target.selection?.value?.length > 0 ? event.target.selection?.value : null)
    formData.set('categorie', event.target.categorie?.value)

    toast.promise(
        apiAxios.post(`/selection/${event.target.membre.value}`, {
            id: event.target.id.value,
            membre: event.target.membre.value,
            saison: event.target.saison.value,
            categorie: event.target.categorie.value,
        }), getToastMessage("membre.toast.select.save")
    ).then(data => {
        dispatch({type: 'UPDATE_OR_ADD', payload: data.data})
        dispatch({type: 'SORT'})
    })

}

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

function ModalContent({selection, dispatch}) {
    const [saison, setSaison] = useState(0)
    const [cat, setCat] = useState("")
    const [isNew, setNew] = useState(true)
    const {t} = useTranslation();

    const setSeason = (event) => {
        setSaison(Number(event.target.value))
    }
    const handleCatChange = (event) => {
        setCat(event.target.value);
    }

    useEffect(() => {
        if (selection.id !== -1) {
            setNew(false)
            setSaison(selection.saison)
        } else {
            setNew(true)
            setSaison(getSaison())
        }
        setCat(selection.categorie)
    }, [selection]);

    return <form onSubmit={e => sendSelection(e, dispatch)}>
        <input name="id" value={selection.id} readOnly hidden/>
        <input name="membre" value={selection.membre} readOnly hidden/>
        <div className="modal-header">
            <h1 className="modal-title fs-5" id="SelectionModalLabel">{t('editionDeLaSéléction')}</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={t('saison')} name="saison"
                             aria-label={t('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>

            <div className="input-group mb-3">
                <label className="input-group-text" htmlFor="inputGroupSelect01">{t('catégorie')}</label>
                <select className="form-select" id="inputGroupSelect01" value={cat} onChange={handleCatChange} name="categorie" required>
                    <option>{t('choisir...')}</option>
                    {CatList.map((cat) => {
                        return (<option key={cat} value={cat}>{getCatName(cat)}</option>)
                    })}
                </select>
            </div>

        </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={() => removeSelection(selection.id, dispatch)}>{t('button.supprimer')}</button>}
        </div>
    </form>
}
