import React, {useEffect, useRef, useState} from "react";
import {usePubAffDispatch} from "../../../hooks/useExternalWindow.jsx";
import {timePrint} from "../../../utils/Tools.js";
import {useTranslation} from "react-i18next";
import {useWS} from "../../../hooks/useWS.jsx";

export function ChronoPanel({menuActions}) {
    const [config, setConfig] = useState({
        time: Number(sessionStorage.getItem("chronoTime") || "90999"),
        pause: Number(sessionStorage.getItem("chronoPause") || "60999")
    })
    const [chrono, setChrono] = useState({time: 0, startTime: 0})
    const chronoText = useRef(null)
    const [chronoState, setChronoState] = useState(0)
    const state = useRef({chronoState: 0, countBlink: 20, lastColor: "#000000", lastTimeStr: "00:00"})
    const publicAffDispatch = usePubAffDispatch();
    const {t} = useTranslation("cm");

    const addTime = (time) => setChrono(prev => ({...prev, time: prev.time - time}))
    const isRunning = () => chrono.startTime !== 0

    const getTime = () => {
        if (chrono.startTime === 0)
            return chrono.time
        return chrono.time + Date.now() - chrono.startTime
    }

    menuActions.current.setTimerConfig = (time, pause) => {
        setConfig({time: time + 999, pause: pause + 999})
    }

    useEffect(() => {
        publicAffDispatch({type: 'CALL_TIME', payload: {timeStr: state.current.lastTimeStr, timeColor: state.current.color}})
    }, [])

    useEffect(() => {
        const blinkRfDuration = 20
        const state_ = state.current
        const text_ = chronoText.current

        publicAffDispatch({type: 'CALL_TIME', payload: {timeStr: state.current.lastTimeStr, timeColor: state.current.color}})

        const timer = setInterval(() => {
            let currentDuration = config.time
            let color = "#000000"
            if (state_.chronoState === 1) {
                color = (state_.countBlink < blinkRfDuration) ? "#000000" : "#ff0000"
            } else if (state_.chronoState === 2) {
                currentDuration = (state_.chronoState === 0) ? 10000 : config.pause
                color = (state_.countBlink < blinkRfDuration) ? "#008000" : "#ff0000"
            }
            const timeStr = timePrint(currentDuration - getTime())

            if (timeStr !== state_.lastTimeStr || color !== state_.lastColor)
                publicAffDispatch({type: 'CALL_TIME', payload: {timeStr: timeStr, timeColor: color}})

            if (timeStr !== state_.lastTimeStr) {
                text_.textContent = timePrint(currentDuration - getTime())
                state_.lastTimeStr = timeStr
            }
            if (color !== state_.lastColor) {
                text_.style.color = color
                state_.lastColor = color
            }

            if (state_.chronoState === 0 && isRunning()) {
                state_.chronoState = 1
                setChronoState(1)
            } else if (state_.chronoState === 1 && getTime() >= config.time) {
                setChrono(prev => ({...prev, time: 0, startTime: Date.now()}))
                state_.chronoState = 2
                setChronoState(2)
            } else if (state_.chronoState === 2 && getTime() >= config.pause) {
                setChrono(prev => ({...prev, time: 0, startTime: Date.now()}))
                state_.chronoState = 1
                setChronoState(1)
            }

            if (isRunning()) {
                state_.countBlink = 19
            } else {
                state_.countBlink++
                if (state_.countBlink > 40)
                    state_.countBlink = 0
            }
            if (state_.chronoState === 0) {
                clearInterval(timer)
            }
        }, 50);
        return () => clearInterval(timer)
    }, [chrono, config])

    const handleSubmit = (e) => {
        e.preventDefault();
        const form = e.target;
        const timeStr = form[0].value;
        const pauseStr = form[1].value;

        const parseTime = (str) => {
            const parts = str.split(":").map(part => parseInt(part, 10));
            if (parts.length === 1) {
                return parts[0] * 1000;
            } else if (parts.length === 2) {
                return (parts[0] * 60 + parts[1]) * 1000;
            } else {
                return 0;
            }
        }

        const newTime = parseTime(timeStr) + 999;
        const newPause = parseTime(pauseStr) + 999;

        sessionStorage.setItem("chronoPause", newPause);
        sessionStorage.setItem("chronoTime", newTime);

        setConfig({time: newTime, pause: newPause});
    }

    return <div>
        <div className="row">
            <button className="btn btn-primary col-6 col-sm-8 col-md-9"
                    onClick={__ => isRunning() ?
                        setChrono(prev => ({...prev, time: prev.time + Date.now() - prev.startTime, startTime: 0})) :
                        setChrono(prev => ({...prev, startTime: Date.now()}))}>
                {isRunning() ? t('chrono.arrêter') : t('chrono.démarrer')}</button>
            <button className="btn btn-danger col" onClick={__ => {
                setChrono(prev => ({...prev, time: 0, startTime: 0}))
                state.current.chronoState = 0
                setChronoState(0)
            }}>{t('réinitialiser')}
            </button>
        </div>
        <div className="row" style={{marginTop: "0.5em"}}>
            <div className="col-12 col-sm-8 col-md-9">
                <h1 ref={chronoText}
                    style={{fontSize: "min(19vw, 7.5em)", textAlign: "center", color: state.current.lastColor}}>{state.current.lastTimeStr}</h1>
            </div>
            <div className="col" style={{margin: "auto 0"}}>
                <div className="row">
                    <button className="btn btn-outline-secondary col-6" onClick={__ => addTime(-10000)}>{t('chrono.-10S')}</button>
                    <button className="btn btn-outline-secondary col-6" onClick={__ => addTime(10000)}>{t('chrono.+10S')}</button>
                </div>
                <div className="row" style={{marginTop: "0.5em"}}>
                    <button className="btn btn-outline-secondary col-6" onClick={__ => addTime(-1000)}>{t('chrono.-1S')}</button>
                    <button className="btn btn-outline-secondary col-6" onClick={__ => addTime(1000)}>{t('chrono.+1S')}</button>
                </div>
                <div className="row" style={{marginTop: "0.5em"}}>
                    <button className="btn btn-outline-secondary col-12" onClick={__ => {
                        const timeStr = prompt(t('chrono.entrezLeTempsEnS'), "0");
                        if (timeStr === null)
                            return;
                        addTime(parseInt(timeStr, 10) * 1000);
                    }}>{t('chrono.+/-...S')}
                    </button>
                </div>
            </div>
        </div>
        <div className="row" style={{marginTop: "0.5em"}}>
            <div className="col-12 col-sm-8" style={{margin: 'auto 0'}}>
                <div>{t('chrono.recapTemps', {temps: timePrint(config.time), pause: timePrint(config.pause)})}</div>
            </div>
            <button className="btn btn-secondary col" data-bs-toggle="modal" data-bs-target="#timeModal">{t('chrono.définirLeTemps')}
            </button>
        </div>

        <div className="modal fade" id="timeModal" tabIndex="-1" aria-labelledby="timeModalLabel" aria-hidden="true">
            <div className="modal-dialog">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title">{t('chrono.editionTemps')}</h5>
                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <form onSubmit={handleSubmit}>
                        <div className="modal-body">
                            <div className="input-group mb-3">
                                <span className="input-group-text">{t('duréeRound')}</span>
                                <input type="text" className="form-control" placeholder="0" aria-label="Min" defaultValue={timePrint(config.time)}/>
                                <span className="input-group-text">(mm:ss)</span>
                            </div>
                            <div className="input-group mb-3">
                                <span className="input-group-text">{t('duréePause')}</span>
                                <input type="text" className="form-control" placeholder="0" aria-label="Min" defaultValue={timePrint(config.pause)}/>
                                <span className="input-group-text">(mm:ss)</span>
                            </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('valider')}</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>

        <SendChrono chrono={chrono} config={config} chronoState={chronoState}/>
    </div>
}

function SendChrono({chrono, config, chronoState}) {
    const {sendNotify, setState} = useWS();

    useEffect(() => {
        setState({chronoState: {...chrono, configTime: config.time, configPause: config.pause, state: chronoState}});
        sendNotify("sendCurentChrono", {...chrono, configTime: config.time, configPause: config.pause, state: chronoState});
    }, [chrono]);

    return <>
    </>
}
