import {useEffect, useState} from "react";
import {apiAxios, errFormater, getSaison} from "../utils/Tools.js";
import {toast} from "react-toastify";
import {useLocation, useNavigate} from "react-router-dom";

const notUpperCase = ["de", "la", "le", "les", "des", "du", "d'", "l'", "sur"];

function formatAdresse(data) {
    const words = data.split(" ");

    return words.map((word) => {
        if (notUpperCase.includes(word.toLowerCase())) {
            return word.toLowerCase();
        }
        return word[0].toUpperCase() + word.substring(1).toLowerCase();
    }).join(" ");
}

function reconstruireAdresse(infos) {
    console.log(infos);
    let adresseReconstruite = "";

    if (infos.numero_voie === null) {
        if (infos.complement_adresse) {
            adresseReconstruite += formatAdresse(infos.complement_adresse) + ', ';
        }
    } else {
        adresseReconstruite += infos.numero_voie + ' ';
    }

    adresseReconstruite += formatAdresse(infos.type_voie) + ' ';
    adresseReconstruite += formatAdresse(infos.libelle_voie) + ', ';
    adresseReconstruite += infos.code_postal + ' ' + infos.libelle_commune + ', ';

    if (infos.complement_adresse && infos.numero_voie !== null) {
        adresseReconstruite += formatAdresse(infos.complement_adresse) + ', ';
    }
    if (infos.code_cedex && infos.libelle_cedex) {
        adresseReconstruite += 'Cedex ' + infos.code_cedex + ' - ' + infos.libelle_cedex;
    }

    if (adresseReconstruite.endsWith(', ')) {
        adresseReconstruite = adresseReconstruite.slice(0, -2);
    }

    return adresseReconstruite;
}

function getSaisonToAff(currentDate = new Date()) {
    if (currentDate.getMonth() >= 7) { //aout et plus
        return currentDate.getFullYear()
    } else {
        return currentDate.getFullYear() - 1
    }
}

export function DemandeAff() {
    const {hash} = useLocation();
    const navigate = useNavigate();
    const [initData, setInitData] = useState(null)
    const [needFile, setNeedFile] = useState(true)

    useEffect(() => {
        if (hash.startsWith("#d")) {
            const data = JSON.parse(decodeURI(hash.substring(2)));
            setInitData(data)
            setNeedFile(false)
        } else if (hash.startsWith("#e")) {
            apiAxios.get(`/affiliation/request/${hash.substring(2)}`).then(data => {
                for (let i = 0; i < data.data.members.length; i++) {
                    if (data.data.members[i].licence === -1)
                        data.data.members[i].licence = ""
                }
                setInitData(data.data)
                setNeedFile(false)
            }).catch(_ => {
                setInitData({})
            })
        } else {
            setInitData({})
        }
    }, []);

    const submit = (event) => {
        event.preventDefault()
        const formData = new FormData(event.target)
        formData.append("m1_role", event.target.m1_role?.value)
        formData.append("rna", event.target.rna?.value)
        formData.append("siret", event.target.siret?.value)

        let error = false;
        for (let i = 1; i <= 3; i++) {
            if (event.target[`m${i}_role`]?.value === "0") {
                toast.error(`Le rôle du membre ${i} est obligatoire`)
                error = true;
            }
        }
        if (error) {
            return;
        }

        if (event.nativeEvent.submitter.value === "undo") {
            toast.promise(
                apiAxios.delete(`/affiliation/request/${initData.id}`),
                {
                    pending: "Annulation de la demande d'affiliation en cours",
                    success: "Demande d'affiliation annulée avec succès 🎉",
                    error: {
                        render({data}) {
                            return errFormater(data, "Échec de l'annulation de la demande d'affiliation")
                        }
                    }
                }
            ).then(_ => {
                navigate("/club/me")
            })
        } else if (event.nativeEvent.submitter.value === "edit") {
            formData.append("id", initData.id)

            toast.promise(
                apiAxios.put(`/affiliation/request/edit`, formData),
                {
                    pending: "Enregistrement des modifications en cours",
                    success: "Modifications enregistrées avec succès 🎉",
                    error: {
                        render({data}) {
                            return errFormater(data, "Échec de l'enregistrement des modifications")
                        }
                    }
                }
            ).then(_ => {
                navigate("/club/me")
            })
        } else {
            formData.append("id", -1)

            toast.promise(
                apiAxios.post(`/affiliation/request`, formData, {headers: {'Accept': '*/*'}}),
                {
                    pending: "Enregistrement de la demande d'affiliation en cours",
                    success: "Demande d'affiliation enregistrée avec succès 🎉",
                    error: {
                        render({data}) {
                            return errFormater(data, "Échec de la demande d'affiliation")
                        }
                    }
                }
            ).then(_ => {
                navigate("/affiliation/ok")
            })
        }
    }

    return <div>
        <h1>Demande d'affiliation {getSaisonToAff() + "-" + (getSaisonToAff() + 1)}</h1>
        <p>L'affiliation est annuelle et valable pour une saison sportive : du 1er septembre au 31 août de l’année
            suivante.</p>
        Pour s’affilier, une association sportive doit réunir les conditions suivantes :
        <ul>
            <li>Avoir son siège social en France ou Principauté de Monaco</li>
            <li>Être constituée conformément au chapitre 1er du titre II du livre 1er du Code du Sport</li>
            <li>Poursuivre un objet social entrant dans la définition de l’article 1 des statuts de la Fédération</li>
            <li>Disposer de statuts compatibles avec les principes d’organisation et de fonctionnement de la
                Fédération
            </li>
            <li>Assurer en son sein la liberté d’opinion et le respect des droits de la défense, et s’interdire toute
                discrimination
            </li>
            <li>Respecter les règles d’encadrement, d’hygiène et de sécurité établies par les règlements de la
                Fédération
            </li>
        </ul>

        {initData && <div className="card mb-4">
            <form onSubmit={submit}>
                <div className="card-body">
                    <h4>L'association</h4>
                    <AssoInfo initData={initData} needFile={needFile}/>
                    <h4>Membre n°1</h4>
                    <MembreInfo role="m1" initData={initData.members?.at(0) || {}}/>
                    <h4 style={{marginTop: '1em'}}>Membre n°2</h4>
                    <MembreInfo role="m2" initData={initData.members?.at(1) || {}}/>
                    <h4 style={{marginTop: '1em'}}>Membre n°3</h4>
                    <MembreInfo role="m3" initData={initData.members?.at(2) || {}}/>

                    <div className="mb-3" style={{marginTop: '1em'}}>
                        {!initData.id && <p>Après validation de votre demande, vous recevrez un identifiant et mot de passe provisoire pour
                            accéder à votre espace FFSAF</p>}
                        Notez que pour finaliser votre affiliation, il vous faudra :
                        <ul>
                            <li>Disposer d’au moins trois membres licenciés, dont le président</li>
                            <li>S'être acquitté des cotisations prévues par les règlements fédéraux</li>
                        </ul>
                    </div>

                    {!initData.id ?
                        <div className="row">
                            <div className="d-grid gap-2 d-md-flex justify-content-md-center">
                                <button type="submit" value="new" className="btn btn-primary">Confirmer ma demande d'affiliation
                                </button>
                            </div>
                        </div> :
                        <div className="row">
                            <div className="d-grid gap-2 d-md-flex justify-content-md-center col">
                                <button type="submit" value="undo" className="btn btn-danger">Annuler ma demande
                                </button>
                            </div>
                            <div className="d-grid gap-2 d-md-flex justify-content-md-center col">
                                <button type="submit" value="edit" className="btn btn-primary">Enregistrer les modifications
                                </button>
                            </div>
                        </div>
                    }
                </div>
            </form>
        </div>}
    </div>
}

function AssoInfo({initData, needFile}) {
    const [denomination, setDenomination] = useState("")
    const [siret, setSiret] = useState(initData.siret ? String(initData.siret) : "")
    const [rna, setRna] = useState(initData.rna ? initData.rna : "")
    const [rnaEnable, setRnaEnable] = useState(false)
    const [adresse, setAdresse] = useState(initData.address ? initData.address : "")
    const [contact, setContact] = useState(initData.contact ? initData.contact : "")

    const fetchSiret = () => {
        if (siret.length < 14) {
            toast.error("Le SIRET doit contenir 14 chiffres")
            return;
        }

        toast.promise(
            apiAxios.get(`asso/siren/${siret.substring(0, siret.length - 5)}`),
            {
                pending: "Recherche de l'association en cours",
                success: "Association trouvée avec succès 🎉",
                error: {
                    render({data}) {
                        return errFormater(data, "Échec de la recherche de l'association")
                    }
                }
            }
        ).then(data => {
            const data2 = data.data.unite_legale
            setDenomination(data2.denomination)
            setRnaEnable(data2.identifiant_association === null)
            setRna(data2.identifiant_association ? data2.identifiant_association : "")
            if (!initData.saison || adresse === "")
                setAdresse(reconstruireAdresse(data2.etablissement_siege))
        })
    }
    return <>
        <input name="saison" value={getSaisonToAff()} readOnly hidden/>

        <div className="input-group mb-3">
            <span className="input-group-text" id="basic-addon1">Nom de l'association*</span>
            <input type="text" className="form-control" placeholder="Nom de l'association" name="name"
                   aria-label="Nom de l'association"
                   aria-describedby="basic-addon1" required defaultValue={initData.name ? initData.name : ""}/>
        </div>

        <div className="input-group mb-3">
            <span className="input-group-text">N° SIRET*</span>
            <input type="number" className="form-control" placeholder="siret" name="siret" required value={siret} disabled={!needFile}
                   onChange={e => setSiret(e.target.value)}/>
            <button className="btn btn-outline-secondary" type="button" id="button-addon2"
                    onClick={fetchSiret}>Rechercher
            </button>
        </div>

        <div className="input-group mb-3">
            <span className="input-group-text" id="basic-addon1">Dénomination</span>
            <input type="text" className="form-control" placeholder="Appuyer sur rechercher pour compléter"
                   aria-label="Dénomination"
                   aria-describedby="basic-addon1" disabled value={denomination} readOnly/>
        </div>

        <div className="input-group mb-3">
            <span className="input-group-text" id="basic-addon1">RNA</span>
            <input type="text" className="form-control" placeholder="RNA" aria-label="RNA"
                   aria-describedby="basic-addon1"
                   disabled={!rnaEnable} name="rna" value={rna} onChange={e => setRna(e.target.value)}/>
        </div>

        <div className="mb-3">
            <div className="input-group">
                <span className="input-group-text" id="basic-addon1">Adresse administrative*</span>
                <input type="text" className="form-control" placeholder="Adresse administrative" aria-label="Adresse administrative"
                       aria-describedby="basic-addon1"
                       required value={adresse} name="adresse" onChange={e => setAdresse(e.target.value)}/>
            </div>
            <div className="form-text" id="adresse">Vous pourrez par la suite, ajouter des adresses visibles publiquement pour vos lieux
                d'entrainement
            </div>
        </div>

        <div className="mb-3">
            <div className="input-group">
                <span className="input-group-text" id="basic-addon1">Contact administratif*</span>
                <input type="email" className="form-control" placeholder="Contact administratif" aria-label="Contact administratif"
                       aria-describedby="basic-addon1"
                       required value={contact} name="contact" onChange={e => setContact(e.target.value)}/>
            </div>
        </div>

        <div className="mb-3">
            <div className="input-group">
                <label className="input-group-text" htmlFor="logo">Blason{needFile && "*"}</label>
                <input type="file" className="form-control" id="logo" name="logo" accept=".jpg,.jpeg,.gif,.png,.svg"
                       required={needFile}/>
            </div>
            {!needFile && <div className="form-text" id="status">Laissez vide pour ne rien changer. (Si un blason a déjà été envoyé lors de cette
                demande, il sera utilisé, sinon nous utiliserons celui de la précédant affiliation)</div>}
        </div>

        <div className="mb-3">
            <div className="input-group">
                <label className="input-group-text" htmlFor="status">Statue{needFile && "*"}</label>
                <input type="file" className="form-control" id="status" name="status" accept=".pdf,.txt" required={needFile}/>
            </div>
            {!needFile && <div className="form-text" id="status">Laissez vide pour ne rien changer. (Si un statu a déjà été envoyé lors de cette
                demande, il sera utilisé, sinon nous utiliserons celui de la précédant affiliation)</div>}
        </div>
    </>;
}

function MembreInfo({role, initData}) {
    const [switchOn, setSwitchOn] = useState(!!initData.licence);

    return <>
        <div className="input-group mb-3">
            <label className="input-group-text" htmlFor="inputGroupSelect01">Rôles</label>
            <select className="form-select" id="inputGroupSelect01" defaultValue={initData.role ? initData.role : (role === "m1" ? "PRESIDENT" : 0)}
                    disabled={initData.role ? initData.role === "PRESIDENT" : role === "m1"} name={role + "_role"} required>
                <option value="0">Sélectionner...</option>
                <option value="PRESIDENT">Président</option>
                <option value="TRESORIER">Trésorier</option>
                <option value="SECRETAIRE">Secrétaire</option>
                <option value="VPRESIDENT">Vise-Président</option>
                <option value="VTRESORIER">Vise-Trésorier</option>
                <option value="VSECRETAIRE">Vise-Secrétaire</option>
                <option value="MEMBREBUREAU">Membre du bureau</option>
            </select>
        </div>

        <div className="row g-3 mb-3">
            <div className="col-sm-3">
                <div className="form-floating">
                    <input type="text" className="form-control" id="floatingInput" placeholder="Nom" name={role + "_nom"}
                           defaultValue={initData.lname ? initData.lname : ""} required/>
                    <label htmlFor="floatingInput">Nom*</label>
                </div>
            </div>
            <div className="col-sm-3">
                <div className="form-floating">
                    <input type="text" className="form-control" id="floatingInput" placeholder="Prénom"
                           name={role + "_prenom"} defaultValue={initData.fname ? initData.fname : ""} required/>
                    <label htmlFor="floatingInput">Prénom*</label>
                </div>
            </div>
            <div className="col-sm-5">
                <div className="form-floating">
                    <input type="email" className="form-control" id="floatingInput" placeholder="name@example.com"
                           name={role + "_mail"} defaultValue={initData.email ? initData.email : ""} required/>
                    <label htmlFor="floatingInput">Email*</label>
                </div>
            </div>
        </div>

        <div className="input-group mb-3">
            <label className="input-group-text" htmlFor="inputGroupSelect01">Dispose déjà d'une licence</label>
            <div className="input-group-text">
                <input type="checkbox" id="inputGroupSelect01" className="form-check-input mt-0"
                       checked={switchOn} onChange={() => setSwitchOn(!switchOn)}/>
            </div>
        </div>
        {switchOn &&
            <div className="col-sm-3">
                <div className="form-floating">
                    <input type="number" className="form-control" id="floatingInput" placeholder="N° Licence"
                           name={role + "_licence"} defaultValue={initData.licence ? Number(initData.licence) : ""} required/>
                    <label htmlFor="floatingInput">N° Licence</label>
                </div>
            </div>
        }

    </>
}

export function DemandeAffOk() {
    return (
        <div>
            <h1 className="text-green-800 text-4xl">Demande d'affiliation envoyée avec succès</h1>
            <p>Une fois votre demande validée, vous recevrez un identifiant et mot de passe provisoire pour accéder à votre
                espace FFSAF</p>
        </div>
    );
}
