import './App.css';
import {useEffect, useRef, useState} from "react";

//Spoiler
const Spoiler = ({header="+", open=true, children}) => {
    const [stateOpen, setOpen] = useState(open)
    return (
        <div onClick={e => setOpen(!stateOpen)}>
            {header}
            {stateOpen && children}
        </div>
    )
}

//RangeInput
const RangeInput = ({min, max}) => {
    let [length, setLength] = useState(0)
    return (
        <>
            <span>RangeInput</span>
            <input style={{border: `${(length < min || length > max) ? '1px solid red' : '1px solid black'}`}} type='text'
                   onChange={e => setLength(+e.target.value.length)}/>
        </>
    )
}

//PasswordConfirm
const PasswordItem = ({min}) => {
    let [value, setValue] = useState('')
    return (
        <>
            {value.toLowerCase() !== value && <span>Пароль не должен содержать заглавных букв!</span>}
            {value.search(/\d/) !== -1 && <span>Пароль не должен содержать цифры!</span>}
            <input style={{border: `${value.length < min ? '1px solid red' : '1px solid black'}`}}
                   type='password' value={value} onChange={e => setValue(e.target.value)}/>
        </>
    )
}
const PasswordConfirm = ({min}) => {
    return (
        <form>
            <span>PasswordConfirm</span><br/>
            <PasswordItem min={min}/><br/>
            <PasswordItem min={min}/><br/>
        </form>
    )
}

//Timer
const Timer = ({sec=10}) => {
    const [seconds, setSeconds] = useState(sec);
    const [isActive, setIsActive] = useState(true);

    useEffect(() => {
        let interval = null;
        if (isActive) {
            interval = setInterval(() => {
                setSeconds(seconds => seconds - 1);
            }, 1000);
        }
        else if (!isActive || seconds !== 0) {
            clearInterval(interval);
        }
        if (seconds <= 0){
            clearInterval(interval);
        }
        return () => clearInterval(interval);
    }, [isActive, seconds]);

    function pause() {
        setIsActive(!isActive);
    }

    let h = Math.floor(seconds / 3600);
    let divisor_for_minutes = seconds % 3600;
    let m = Math.floor(divisor_for_minutes / 60);
    let divisor_for_seconds = divisor_for_minutes % 60;
    let s = Math.ceil(divisor_for_seconds);

    return (
        <div>
            <span>
                {h < 10 ? '0' + h : h}:
                {m < 10 ? '0' + m : m}:
                {s < 10 ? '0' + s : s}
            </span>
            <button onClick={pause}>
                {isActive ? 'Pause' : 'Start'}
            </button>
        </div>
    );
}

//TimerControl
const TimerControl = ({hours, minutes, seconds}) => {
    const [timers, setTimer] = useState([])
    let [h, setH] = useState(hours)
    let [m, setM] = useState(minutes)
    let [s, setS] = useState(seconds)
    let finalSec = (h * 3600) + (m * 60) + +s
    console.log(finalSec)
    return (
        <>
            <input value={h.toString()} type='number' min='0' max='23' placeholder='hours' onChange={e => setH(e.target.value)}/>
            <input value={m.toString()} type='number' min='0' max='59' placeholder='minutes' onChange={e => setM(e.target.value)}/>
            <input value={s.toString()} type='number' min='0' max='59' placeholder='seconds' onChange={e => setS(e.target.value)}/>
            <button onClick={() => setTimer([Math.random(), ...timers])}>Start</button>
            {timers.map(i => <Timer sec={finalSec} key={i}/>)}
        </>
    )
}

//TimerContainer
const SecondsTimer = ({seconds}) => <h2>{seconds || 0}</h2>
const TimerContainer = ({seconds, refresh, render}) => {
    const Render = render
    const [counter, setCounter] = useState(seconds)
    const startTime = useRef()
    let flag = true
    if(counter <= 0) flag = false

    useEffect(() => {
        let interval = null
        if (flag) {
            startTime.current = performance.now()
            interval = setInterval(() => {
                setCounter(counter => counter - 1);
            }, refresh);
        }
        return () => clearInterval(interval)
    }, [flag, seconds])

    return (
        <Render seconds={+(seconds - (performance.now() - startTime.current) / refresh).toFixed(0)}/>
    )
}

//LCD
const Timer2 = ({sec=10}) => {
    let h = Math.floor(sec / 3600);
    let divisor_for_minutes = sec % 3600;
    let m = Math.floor(divisor_for_minutes / 60);
    let divisor_for_seconds = divisor_for_minutes % 60;
    let s = Math.ceil(divisor_for_seconds);
    return (
        <div>
            <span>
                {h < 10 ? '0' + h : (h || '00')}:
                {m < 10 ? '0' + m : (m || '00')}:
                {s < 10 ? '0' + s : (s || '00')}
            </span>
        </div>
    );
}
const TimerContainer2 = ({seconds, refresh, render}) => {
    const Render = render
    let refer = useRef()
    let [counter, setCounter] = useState(seconds)
    const startTime = useRef()
    let flag = true
    if(counter <= 0) flag = false

    useEffect(() => {
        let interval = null
        if (flag) {
            startTime.current = performance.now()
            interval = setInterval(() => {
                setCounter(counter => counter - 1);
            }, refresh);
        }
        return () => clearInterval(interval)
    }, [flag])

    return (
        <Render sec={+(seconds - (performance.now() - startTime.current) / refresh).toFixed(0)}/>
    )
}

//Watch
const Watch = ({sec=10}) => {
    let h = Math.floor(sec / 3600);
    let divisor_for_minutes = sec % 3600;
    let m = Math.floor(divisor_for_minutes / 60);
    let divisor_for_seconds = divisor_for_minutes % 60;
    let s = Math.ceil(divisor_for_seconds);

    let sRotate = (360 / 60) * s
    let mRotate = (((m * 60) + s) / 10) % 360
    let hRotate = (((((h) * 60) + m) * 60 + s) / 120) % 360

    return (
        <div>
            <div>
                <span>
                    {h < 10 ? '0' + h : (h || '00')}:
                    {m < 10 ? '0' + m : (m || '00')}:
                    {s < 10 ? '0' + s : (s || '00')}
                </span>
            </div>
            <div className="container-watch">
                <div style={{transform: `rotate(${sRotate}deg)`}} className="arrow-s"></div>
                <div style={{transform: `rotate(${mRotate}deg)`}} className="arrow-m"></div>
                <div style={{transform: `rotate(${hRotate}deg)`}} className="arrow-h"></div>
            </div>
        </div>
    )
}

//TimerControl + TimerContainer
const TimerControl2 = ({hours, minutes, seconds}) => {
    const [timers, setTimer] = useState([])
    let [h, setH] = useState(hours)
    let [m, setM] = useState(minutes)
    let [s, setS] = useState(seconds)
    let finalSec = (h * 3600) + (m * 60) + s
    return (
        <>
            <input value={h.toString()} type='number' min='0' max='23' placeholder='hours' onChange={e => setH(e.target.value)}/>
            <input value={m.toString()} type='number' min='0' max='59' placeholder='minutes' onChange={e => setM(e.target.value)}/>
            <input value={s.toString()} type='number' min='0' max='59' placeholder='seconds' onChange={e => setS(e.target.value)}/>
            <button onClick={() => setTimer([Math.random(), ...timers])}>Start</button>
            {timers.map(i => <TimerContainer2 key={i} seconds={finalSec} refresh={100} render={Timer2}/>)}
        </>
    )
}

function App() {
  return (
       <>
        <Spoiler header={<h1>Заголовок</h1>} open>
          Контент 1
          <p>
            лорем ипсум траливали и тп.
          </p>
        </Spoiler>
        <Spoiler>
          <h2>Контент 2</h2>
          <p>
            лорем ипсум траливали и тп.
          </p>
        </Spoiler>
          <RangeInput min={2} max={10} /><br/>
          <PasswordConfirm min={2} /><br/>
          <Timer sec={5000}/><br/>
          <TimerControl hours={3} minutes={40} seconds={40}/>
          <TimerContainer seconds={100} refresh={100} render={SecondsTimer}/>
          <TimerContainer2 seconds={100} refresh={100} render={Timer2}/>
           <TimerContainer2  seconds={2000} refresh={100} render={Watch}/>
          <TimerControl2 hours={3} minutes={40} seconds={40}/>
      </>
  );
}

export default App;
