import React, { useState, useEffect, useRef } from 'react';

const WEEKLY_SOLO_POINTS = 5;
const WEEKLY_TOGETHER_POINTS = 5;
const EARNED_POINTS_PASSWORD = 'password';

// Timer durations (in milliseconds)
const FIFTEEN_MINUTES = 15 * 60 * 1000;
const TWO_MINUTES = 2 * 60 * 1000;

function App() {
    const [soloPoints, setSoloPoints] = useState(WEEKLY_SOLO_POINTS);
    const [togetherPoints, setTogetherPoints] = useState(WEEKLY_TOGETHER_POINTS);
    const [earnedPoints, setEarnedPoints] = useState(0);
    const [log, setLog] = useState([]); // e.g., [{ type: 'solo', usedAt: 'ISOString' }, ...]
    const [lastReset, setLastReset] = useState(null); // e.g., 'YYYY-MM-DD'

    // Timer states
    const [timerRunning, setTimerRunning] = useState(false);
    const [timeRemaining, setTimeRemaining] = useState(0);

    // For storing the active timer ID (so we can clear it on unmount)
    const timerRef = useRef(null);
    const intervalRef = useRef(null);

    // -----------------------------
    //    LOAD / SAVE localStorage
    // -----------------------------
    useEffect(() => {
        loadData();
    }, []);

    // Check for weekly reset once data is loaded
    useEffect(() => {
        if (lastReset) {
            resetIfNewWeek();
        }
        // eslint-disable-next-line
    }, [lastReset]);

    // Cleanup timers on unmount
    useEffect(() => {
        return () => {
            if (timerRef.current) clearTimeout(timerRef.current);
            if (intervalRef.current) clearInterval(intervalRef.current);
        };
    }, []);

    const loadData = () => {
        try {
            const storedData = localStorage.getItem('pointsData');
            if (storedData) {
                const dataObj = JSON.parse(storedData);
                setSoloPoints(dataObj.soloPoints ?? WEEKLY_SOLO_POINTS);
                setTogetherPoints(dataObj.togetherPoints ?? WEEKLY_TOGETHER_POINTS);
                setEarnedPoints(dataObj.earnedPoints ?? 0);
                setLog(dataObj.log ?? []);
                setLastReset(dataObj.lastReset ?? null);
            } else {
                // If nothing in localStorage, use defaults
                saveData(
                    WEEKLY_SOLO_POINTS,
                    WEEKLY_TOGETHER_POINTS,
                    0,
                    [],
                    null
                );
            }
        } catch (err) {
            console.error('Error reading localStorage:', err);
        }
    };

    const saveData = (newSolo, newTogether, newEarned, newLog, newLastReset) => {
        const dataObj = {
            soloPoints: newSolo,
            togetherPoints: newTogether,
            earnedPoints: newEarned,
            log: newLog,
            lastReset: newLastReset
        };
        localStorage.setItem('pointsData', JSON.stringify(dataObj));
    };

    // -----------------------------
    //       WEEKLY RESET LOGIC
    // -----------------------------
    // Helper: get Monday of current week as 'YYYY-MM-DD'
    const getMonday = (date = new Date()) => {
        const d = new Date(date);
        const day = d.getDay(); // 0=Sun, 1=Mon, ...
        const diff = d.getDate() - day + (day === 0 ? -6 : 1);
        d.setDate(diff);
        return d.toISOString().split('T')[0];
    };

    const resetIfNewWeek = () => {
        const currentMonday = getMonday();
        if (!lastReset || lastReset !== currentMonday) {
            // Reset solo & together points. Earned points can remain or reset, your choice.
            setSoloPoints(WEEKLY_SOLO_POINTS);
            setTogetherPoints(WEEKLY_TOGETHER_POINTS);
            // setEarnedPoints(0); // Uncomment if you want to reset earned each Monday
            setLastReset(currentMonday);

            saveData(
                WEEKLY_SOLO_POINTS,
                WEEKLY_TOGETHER_POINTS,
                earnedPoints, // or 0 if resetting
                log,
                currentMonday
            );
        }
    };

    // -----------------------------
    //          USE A POINT
    // -----------------------------
    const usePoint = (pointType) => {
        if (pointType === 'solo' && soloPoints <= 0) {
            alert('No Solo points left!');
            return;
        }
        if (pointType === 'together' && togetherPoints <= 0) {
            alert('No Together points left!');
            return;
        }
        if (pointType === 'earned' && earnedPoints <= 0) {
            alert('No Earned points left!');
            return;
        }

        let newSolo = soloPoints;
        let newTogether = togetherPoints;
        let newEarned = earnedPoints;

        if (pointType === 'solo') newSolo = soloPoints - 1;
        if (pointType === 'together') newTogether = togetherPoints - 1;
        if (pointType === 'earned') newEarned = earnedPoints - 1;

        // Log usage
        const usedAt = new Date().toISOString();
        const newLog = [...log, { type: pointType, usedAt }];

        // Update states
        setSoloPoints(newSolo);
        setTogetherPoints(newTogether);
        setEarnedPoints(newEarned);
        setLog(newLog);

        // Persist
        saveData(newSolo, newTogether, newEarned, newLog, lastReset);

        // Start 15-minute timer
        alert(
            `Using 1 ${pointType.toUpperCase()} point at ${usedAt}. \n15-minute timer started.`
        );
        startTimer(FIFTEEN_MINUTES);
    };

    // -----------------------------
    //        TIMERS (Client)
    // -----------------------------
    const startTimer = (duration) => {
        // If a timer is already running, clear it
        if (timerRef.current) clearTimeout(timerRef.current);
        if (intervalRef.current) clearInterval(intervalRef.current);

        setTimerRunning(true);
        setTimeRemaining(duration);

        // Set up a 1-second interval to update the countdown display
        let remaining = duration;
        intervalRef.current = setInterval(() => {
            remaining -= 1000;
            setTimeRemaining(remaining);
            if (remaining <= 0) {
                clearInterval(intervalRef.current);
            }
        }, 1000);

        // When the timer finishes:
        timerRef.current = setTimeout(() => {
            clearInterval(intervalRef.current);
            setTimerRunning(false);
            setTimeRemaining(0);
            ring();
        }, duration);
    };

    const ring = () => {
        const wantsFinishUp = window.confirm(
            '15 minutes are up! \nClick "OK" to start a 2-minute finish-up timer, or "Cancel" to stop.'
        );
        if (wantsFinishUp) {
            startTimer(TWO_MINUTES);
        }
    };

    // -----------------------------
    //       ADD EARNED POINT
    // -----------------------------
    const addEarnedPoint = () => {
        const pw = window.prompt('Enter password to add an earned point:');
        if (pw === EARNED_POINTS_PASSWORD) {
            const newEarned = earnedPoints + 1;
            setEarnedPoints(newEarned);
            saveData(soloPoints, togetherPoints, newEarned, log, lastReset);
            alert('1 Earned Point added!');
        } else {
            alert('Incorrect password!');
        }
    };

    // -----------------------------
    //     DISPLAY TIMER FORMAT
    // -----------------------------
    const formatTime = (ms) => {
        if (ms <= 0) return '00:00';
        const totalSeconds = Math.floor(ms / 1000);
        const minutes = Math.floor(totalSeconds / 60);
        const seconds = totalSeconds % 60;
        const mm = minutes < 10 ? `0${minutes}` : minutes;
        const ss = seconds < 10 ? `0${seconds}` : seconds;
        return `${mm}:${ss}`;
    };

    // -----------------------------
    //           RENDER
    // -----------------------------
    return (
        <div style={styles.container}>
            <h1>Screen-Time Points</h1>
            <div style={styles.pointsRow}>
                <div style={styles.pointsBox}>
                    <p>Solo Points: {soloPoints}</p>
                </div>
                <div style={styles.pointsBox}>
                    <p>Together Points: {togetherPoints}</p>
                </div>
                <div style={styles.pointsBox}>
                    <p>Earned Points: {earnedPoints}</p>
                </div>
            </div>

            <div style={styles.buttonsRow}>
                <button style={styles.button} onClick={() => usePoint('solo')}>
                    Use SOLO Point
                </button>
                <button style={styles.button} onClick={() => usePoint('together')}>
                    Use TOGETHER Point
                </button>
                <button style={styles.button} onClick={addEarnedPoint}>
                    Add EARNED Point
                </button>
                <button style={styles.button} onClick={() => usePoint('earned')}>
                    Use EARNED Point
                </button>
            </div>

            {/* Timer display */}
            {timerRunning && (
                <div style={{ margin: '20px', fontSize: '18px' }}>
                    <strong>Timer Running: {formatTime(timeRemaining)}</strong>
                </div>
            )}

            {/* Recent Logs */}
            <div style={styles.logSection}>
                <h3>Recent Log (last 5)</h3>
                {log.slice(-5).reverse().map((entry, idx) => (
                    <p key={idx}>
                        [{entry.type}] used at {entry.usedAt}
                    </p>
                ))}
            </div>
        </div>
    );
}

// -----------------------------
//         Basic Styles
// -----------------------------
const styles = {
    container: {
        maxWidth: 600,
        margin: '40px auto',
        fontFamily: 'sans-serif',
        textAlign: 'center',
    },
    pointsRow: {
        display: 'flex',
        justifyContent: 'space-around',
        marginBottom: 20,
    },
    pointsBox: {
        border: '1px solid #aaa',
        borderRadius: 4,
        padding: '10px 20px',
        minWidth: 100,
        backgroundColor: '#f9f9f9'
    },
    buttonsRow: {
        display: 'flex',
        justifyContent: 'space-around',
        marginBottom: 30,
    },
    button: {
        padding: '10px 15px',
        fontSize: '14px',
        cursor: 'pointer',
        backgroundColor: '#0066cc',
        color: '#fff',
        border: 'none',
        borderRadius: 4,
    },
    logSection: {
        textAlign: 'left',
        marginTop: 30,
        padding: '0 20px',
    },
};

export default App;
