import React, {useEffect, useRef, useState} from "react";
import {useRequestWS, useWS} from "../../../hooks/useWS.jsx";
import {useCombs, useCombsDispatch} from "../../../hooks/useComb.jsx";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {createPortal} from "react-dom";
import {copyStyles} from "../../../utils/copyStyles.js";
import {PubAffProvider, usePubAffDispatch, usePubAffState} from "../../../hooks/useExternalWindow.jsx";
import {faArrowRightArrowLeft, faDisplay, faFile} from "@fortawesome/free-solid-svg-icons";
import {PubAffWindow} from "./PubAffWindow.jsx";
import {SimpleIconsScore} from "../../../assets/SimpleIconsScore.ts";
import {ChronoPanel} from "./CMTChronoPanel.jsx";
import {CategorieSelect} from "./CMTMatchPanel.jsx";
import {PointPanel} from "./CMTPoint.jsx";
import {importOBSConfiguration, OBSProvider, useOBS} from "../../../hooks/useOBS.jsx";
import {SimpleIconsOBS} from "../../../assets/SimpleIconsOBS.ts";
import {Flip, toast} from "react-toastify";
import {useTranslation} from "react-i18next";
import {getToastMessage} from "../../../utils/Tools.js";

export function CMTable() {
    const combDispatch = useCombsDispatch()
    const [catId, setCatId] = useState(-1);
    const menuActions = useRef({});
    const {data} = useRequestWS("getRegister", null)
    const {t} = useTranslation("cm");

    useEffect(() => {
        if (data === null)
            return;
        combDispatch({type: 'SET_ALL', payload: {source: "register", data: data}});
    }, [data]);

    return <OBSProvider>
        <PubAffProvider>
            <div className="text-center">
                <div className="row">
                    <div className="col-md-12 col-lg">
                        <div className="card mb-3">
                            <div className="card-header">{t('chronomètre')}</div>
                            <div className="card-body">
                                <ChronoPanel menuActions={menuActions}/>
                            </div>
                        </div>

                        <div className="card mb-3">
                            <div className="card-header">{t('score')}</div>
                            <div className="card-body">
                                <PointPanel menuActions={menuActions}/>
                            </div>
                        </div>

                        <div id="infoCategory"></div>
                    </div>
                    <div className="col-md-12 col-xl-6 col-xxl-5">
                        <div className="card mb-3">
                            <div className="card-header">{t('matches')}</div>
                            <div className="card-body">
                                <CategorieSelect catId={catId} setCatId={setCatId} menuActions={menuActions}/>
                            </div>
                        </div>
                    </div>
                </div>
                <Menu menuActions={menuActions}/>
                <ObsAutoSyncWhitPubAff/>
                <SendCatId catId={catId}/>
            </div>
        </PubAffProvider>
    </OBSProvider>
}

const windowName = "FFSAFScorePublicWindow";

let tto = [];

function Menu({menuActions}) {
    const e = document.getElementById("actionMenu")
    const publicAffDispatch = usePubAffDispatch()
    const [showPubAff, setShowPubAff] = useState(false)
    const [showScore, setShowScore] = useState(true)
    const [zone, setZone] = useState(sessionStorage.getItem("liceName") || "???")
    const {connected, connect, disconnect} = useOBS();
    const longPress = useRef({time: null, timer: null, button: null});
    const obsModal = useRef(null);
    const teamCardModal = useRef(null);
    const {t} = useTranslation("cm");

    const externalWindow = useRef(null)
    const containerEl = useRef(document.createElement("div"))

    useEffect(() => {
        if (sessionStorage.getItem(windowName + "_open") === "true") {
            handlePubAff();
        }
    }, []);

    const handlePubAff = __ => {
        if (showPubAff === false || !externalWindow.current || externalWindow.current.closed) {
            externalWindow.current = window.open("", windowName, "width=800,height=600,left=200,top=200")
            externalWindow.current.document.body.innerHTML = ""
            externalWindow.current.document.body.appendChild(containerEl.current)
            copyStyles(document, externalWindow.current.document)

            externalWindow.current.addEventListener("beforeunload", () => {
                setShowPubAff(false);
                externalWindow.current.close();
                externalWindow.current = null;
                publicAffDispatch({type: 'CLEAR_CB_TIME', payload: null});
                sessionStorage.removeItem(windowName + "_open");
            });
            setShowPubAff(true);
            sessionStorage.setItem(windowName + "_open", "true");
        } else {
            externalWindow.current.focus();
        }
    }

    for (const x of tto)
        x.dispose();
    const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip2"]')
    tto = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))

    const handleScore = __ => {
        setShowScore(!showScore);
        publicAffDispatch({type: 'SET_DATA', payload: {showScore: !showScore}});
    }

    const handleSwitchScore = () => {
        menuActions.current.switchSore?.();
    }

    const longTimeAction = (button) => {
        if (button === "obs") {
            // obsModal.current.click();
        }
    }

    const longPressDown = (button) => {
        longPress.current.button = button;
        longPress.current.time = new Date();
        longPress.current.timer = setTimeout(() => {
            longTimeAction(button);

            longPress.current.time = null;
            longPress.current.button = null;
        }, 1000);
    }

    const longPressUp = (button) => {
        clearTimeout(longPress.current.timer);

        if (longPress.current.time) {
            const diff = new Date() - longPress.current.time;
            if (longPress.current.button === button) {
                if (diff >= 1000) {
                    longTimeAction(button);
                } else {
                    if (button === "obs") {
                        if (connected) {
                            disconnect();
                        } else {
                            importOBSConfiguration()
                                .then(config => {
                                    connect(config.adresse, config.password, config.assets_dir);
                                })
                                .catch(() => {
                                    toast.error(t('aucuneConfigurationObs'));
                                });
                        }
                    }
                }
            }

            longPress.current.time = null;
            longPress.current.button = null;
        }
    }

    const handleLiceSubmit = (e) => {
        e.preventDefault();
        const form = e.target;
        const prefix = form[0].value;

        if (prefix === "") {
            sessionStorage.removeItem("liceName");
            setZone("???");
            return;
        }

        sessionStorage.setItem("liceName", prefix);
        setZone(prefix);
    }

    if (!e)
        return <></>;
    return <>
        {createPortal(
            <>
                <div className="vr" style={{margin: "0 0.5em", height: "100%"}}></div>
                <span onClick={() => obsModal.current.click()} style={{cursor: "pointer"}}>Zone {zone}</span>
                <div className="vr" style={{margin: "0 0.5em", height: "100%"}}></div>
                <FontAwesomeIcon icon={faFile} size="xl" style={{color: "#6c757d", cursor: "pointer", marginRight: "0.25em"}}
                                 onClick={() => teamCardModal.current.click()} data-bs-toggle="tooltip2" data-bs-placement="top"
                                 data-bs-title={t('cartonDéquipe')}/>
                <FontAwesomeIcon icon={faArrowRightArrowLeft} size="xl" style={{color: "#6c757d", cursor: "pointer", marginRight: "0.25em"}}
                                 onClick={handleSwitchScore} data-bs-toggle="tooltip2" data-bs-placement="top"
                                 data-bs-title={t('ttm.table.inverserLaPosition')}/>
                <FontAwesomeIcon icon={SimpleIconsOBS} size="xl"
                                 style={{color: connected ? "#00c700" : "#6c757d", cursor: "pointer"}}
                                 onMouseDown={() => longPressDown("obs")}
                                 onMouseUp={() => longPressUp("obs")}
                                 data-bs-toggle="tooltip2" data-bs-placement="top"
                                 data-bs-title={t('ttm.table.obs')}/>
                <div className="vr" style={{margin: "0 0.5em", height: "100%"}}></div>
                <FontAwesomeIcon icon={faDisplay} size="xl"
                                 style={{color: showPubAff ? "#00c700" : "#6c757d", cursor: "pointer", marginRight: "0.25em"}}
                                 onClick={handlePubAff}
                                 data-bs-toggle="tooltip2" data-bs-placement="top" data-bs-title={t('ttm.table.pub_aff')}/>
                <FontAwesomeIcon icon={SimpleIconsScore} size="xl" style={{color: showScore ? "#00c700" : "#6c757d", cursor: "pointer"}}
                                 onClick={handleScore}
                                 data-bs-toggle="tooltip2" data-bs-placement="top" data-bs-title={t('ttm.table.pub_score')}/>
            </>, document.getElementById("actionMenu"))}
        {externalWindow.current && createPortal(<PubAffWindow document={externalWindow.current.document}/>, containerEl.current)}

        <button ref={obsModal} type="button" className="btn btn-link" data-bs-toggle="modal" data-bs-target="#LiceNameModal"
                style={{display: 'none'}}>
            Launch Lice Name Modal
        </button>
        <div className="modal fade" id="LiceNameModal" tabIndex="-1" aria-labelledby="LiceNameModalLabel" aria-hidden="true">
            <div className="modal-dialog">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title">{t('configurationDuNomDeLaZone')}</h5>
                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <form onSubmit={handleLiceSubmit}>
                        <div className="modal-body">
                            <div className="input-group mb-3">
                                <span className="input-group-text">{t('nomDeLaZone')}</span>
                                <input type="text" className="form-control" placeholder="1" aria-label="" size={1} minLength={0} maxLength={1}
                                       defaultValue={sessionStorage.getItem("liceName") || "1"}/>
                            </div>
                        </div>
                        <div className="modal-footer">
                            <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">{t('fermer')}</button>
                            <button type="submit" className="btn btn-primary" data-bs-dismiss="modal">{t('sauvegarde')}</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>

        <button ref={teamCardModal} type="button" className="btn btn-link" data-bs-toggle="modal" data-bs-target="#TeamCardModal"
                style={{display: 'none'}}>
            Launch OBS Modal
        </button>
        <div className="modal fade" id="TeamCardModal" tabIndex="-1" aria-labelledby="TeamCardModalLabel" aria-hidden="true">
            <div className="modal-dialog">
                <div className="modal-content">
                    <TeamCardModal/>
                </div>
            </div>
        </div>
        <SendLiceName name={zone}/>
    </>
}

function TeamCardModal() {
    const [club, setClub] = useState("")

    const {t} = useTranslation("cm");
    const {combs} = useCombs()
    const {sendRequest} = useWS()

    let clubList = [];
    if (combs != null) {
        clubList = Object.values(combs).map(d => d.club_str).filter((v, i, a) => v !== "" && v !== undefined && a.indexOf(v) === i);
    }

    const handleAdd = (e) => {
        e.preventDefault();
        toast.promise(sendRequest("applyTeamCards", {
                teamUuid: Object.values(combs).find(d => d.club_str === club)?.club_uuid,
                teamName: club,
                type: "YELLOW"
            }),
            getToastMessage("toast.card.team", "cm"))
            .then(() => {
            })
    }

    return <>
        <div className="modal-header">
            <h5 className="modal-title">{t('cartonDéquipe')}</h5>
            <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">
                <label htmlFor="inputGroupSelect09" className="input-group-text">{t('club')}</label>
                <select id="inputGroupSelect09" className="form-select" value={club} onChange={(e) => setClub(e.target.value)}>
                    {clubList.sort((a, b) => a.localeCompare(b)).map((club, index) => (
                        <option key={index} value={club}>{club}</option>))}
                </select>
                <button className="btn btn-outline-primary" type="button" onClick={handleAdd}>{t("ajouter")}</button>
            </div>
        </div>
        <div className="modal-footer">
            <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">{t('fermer')}</button>
        </div>
    </>
}

function SendLiceName({name}) {
    const {sendNotify, setState} = useWS();

    useEffect(() => {
        setState({liceName: name});
        sendNotify("sendLicenceName", name);
    }, [name]);

    return <>
    </>
}

function SendCatId({catId}) {
    const notifState = useRef(undefined);
    const {sendNotify, setState, dispatch, tableState} = useWS();
    const {t} = useTranslation("cm");

    useEffect(() => {
        const welcomeInfo = () => {
            sendNotify("sendState", tableState.current)
        }
        const sendTeamCards = ({data}) => {
            function content({closeToast, data}) {
                const sendState = (s) => {
                    sendNotify("sendTeamCardReturnState", {
                        state: s,
                        teamUuid: data.teamUuid,
                        teamName: data.teamName,
                        type: data.type,
                        selectedCategory: tableState.current.selectedCategory,
                        selectedMatch: tableState.current.selectedMatch
                    });
                }

                return (
                    <div className="flex items-center w-full">
                        <span>{`Un carton jaune d'équipe a été émis à l'encontre du club ${data.teamName}. Dans votre zone de combat :`}</span><br/>
                        <div className="form-check">
                            <input className="form-check-input" type="radio" name="radioState" id="radioState1"
                                   onChange={e => e.target.checked ? notifState.current = 0 : null}/>
                            <label className="form-check-label" htmlFor="radioState1">
                                Rien n'est en cours
                            </label>
                        </div>
                        <div className="form-check">
                            <input className="form-check-input" type="radio" name="radioState" id="radioState2"
                                   onChange={e => e.target.checked ? notifState.current = 1 : null}/>
                            <label className="form-check-label" htmlFor="radioState2">
                                La categorie est en cours
                            </label>
                        </div>
                        <div className="form-check">
                            <input className="form-check-input" type="radio" name="radioState" id="radioState3"
                                   onChange={e => e.target.checked ? notifState.current = 2 : null}/>
                            <label className="form-check-label" htmlFor="radioState3">
                                Le match est en cours
                            </label>
                        </div>
                        <button className="btn btn-sm btn-outline-primary ml-2" onClick={() => {
                            if (notifState.current === undefined) {
                                return;
                            }
                            sendState(notifState.current)
                            closeToast(true);
                        }}>
                            {t('confirmer')}
                        </button>
                    </div>
                );
            }

            toast.warn(content, {
                position: "top-center",
                autoClose: false,
                closeButton: false,
                hideProgressBar: false,
                closeOnClick: false,
                pauseOnHover: true,
                draggable: false,
                progress: undefined,
                theme: "colored",
                transition: Flip,
                data: {
                    teamUuid: data.teamUuid,
                    teamName: data.teamName,
                    type: data.type,
                }
            });
        }

        welcomeInfo();

        dispatch({type: 'addListener', payload: {callback: welcomeInfo, code: 'welcomeInfo'}})
        dispatch({type: 'addListener', payload: {callback: sendTeamCards, code: 'sendTeamCards'}})
        return () => {
            dispatch({type: 'removeListener', payload: welcomeInfo});
            dispatch({type: 'removeListener', payload: sendTeamCards});

            setState({selectedCategory: -1});
            sendNotify("sendSelectCategory", -1);
        }
    }, []);

    useEffect(() => {
        setState({selectedCategory: catId});
        sendNotify("sendSelectCategory", catId);
    }, [catId]);

    return <>
    </>
}

function ObsAutoSyncWhitPubAff() {
    const {connected, setText, setTextAndColor, setDiapo} = useOBS();
    const oldState = useRef({timeColor: "#000000", timeStr: "--:--", c1: null, c2: null, showScore: true, scoreRouge: 0, scoreBleu: 0});
    const state = usePubAffState();
    const {welcomeData} = useWS();
    const {getComb} = useCombs();

    useEffect(() => {
        if (state.c1 !== oldState.current.c1) {
            const comb = getComb(state.c1);
            setText("comb.rouge", comb ? (comb?.fname + " " + comb?.lname) : "");
            const files = []
            if (comb?.club_uuid && welcomeData.show_blason) files.push(`club_${comb.club_uuid}.png`)
            if (comb?.country && welcomeData.show_flag) files.push(`flag_${comb.country.toLowerCase()}.png`)
            setDiapo("img.rouge", files);
            oldState.current.c1 = state.c1;
        }

        if (state.c2 !== oldState.current.c2) {
            const comb = getComb(state.c2);
            setText("comb.blue", comb ? (comb?.fname + " " + comb?.lname) : "");
            const files = []
            if (comb?.club_uuid && welcomeData.show_blason) files.push(`club_${comb.club_uuid}.png`)
            if (comb?.country && welcomeData.show_flag) files.push(`flag_${comb.country.toLowerCase()}.png`)
            setDiapo("img.blue", files);
            oldState.current.c2 = state.c2;
        }

        if (state.showScore !== oldState.current.showScore) {
            setText("score.rouge", state.showScore ? state.scoreRouge.toString() : "");
            setText("score.blue", state.showScore ? state.scoreBleu.toString() : "");
            oldState.current.showScore = state.showScore;
        }

        if (state.showScore === undefined || state.showScore) {
            if (state.scoreRouge !== oldState.current.scoreRouge) {
                setText("score.rouge", (state.scoreRouge || 0).toString());
                oldState.current.scoreRouge = state.scoreRouge;
            }
            if (state.scoreBleu !== oldState.current.scoreBleu) {
                setText("score.blue", (state.scoreBleu || 0).toString());
                oldState.current.scoreBleu = state.scoreBleu;
            }
        }
    }, [state]);

    state.timeCb2 = (payload) => {
        if (payload.timeStr && payload.timeColor) {
            setTextAndColor("temps", payload.timeStr, payload.timeColor === "#000000" ? "#ffffff" : payload.timeColor);

            oldState.current.timeStr = payload.timeStr;
            oldState.current.lastColor = payload.timeColor;
        }
    }

    useEffect(() => {
        if (!connected)
            return;
        // Initial sync
        const comb = getComb(oldState.current.c1);
        const comb2 = getComb(oldState.current.c2);
        setText("comb.rouge", comb ? (comb?.fname + " " + comb?.lname) : "");
        setText("comb.blue", comb2 ? (comb2?.fname + " " + comb2?.lname) : "");
        setTextAndColor("temps", oldState.current.timeStr, oldState.current.timeColor === "#000000" ? "#ffffff" : oldState.current.timeColor);
        setText("score.rouge", oldState.current.showScore === undefined || oldState.current.showScore ? oldState.current.scoreRouge.toString() : "");
        setText("score.blue", oldState.current.showScore === undefined || oldState.current.showScore ? oldState.current.scoreBleu.toString() : "");

    }, [connected])
}
