/**
 * 12 - Custom Hooks Example
 * 
 * דוגמאות ל-Custom Hooks שימושיים
 * לשימוש חוזר בלוגיקה.
 */

import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';

// ============================================
// Hook 1: useFetch
// ============================================

function useFetch(url) {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        if (!url) {
            setLoading(false);
            return;
        }

        const controller = new AbortController();

        async function fetchData() {
            try {
                setLoading(true);
                setError(null);

                const res = await fetch(url, { signal: controller.signal });
                if (!res.ok) throw new Error(`HTTP ${res.status}`);

                const json = await res.json();
                setData(json);
            } catch (err) {
                if (err.name !== 'AbortError') {
                    setError(err.message);
                }
            } finally {
                setLoading(false);
            }
        }

        fetchData();
        return () => controller.abort();
    }, [url]);

    return { data, loading, error };
}

// ============================================
// Hook 2: useLocalStorage
// ============================================

function useLocalStorage(key, initialValue) {
    const [value, setValue] = useState(() => {
        try {
            const item = localStorage.getItem(key);
            return item ? JSON.parse(item) : initialValue;
        } catch {
            return initialValue;
        }
    });

    useEffect(() => {
        try {
            localStorage.setItem(key, JSON.stringify(value));
        } catch (error) {
            console.error('LocalStorage error:', error);
        }
    }, [key, value]);

    return [value, setValue];
}

// ============================================
// Hook 3: useToggle
// ============================================

function useToggle(initial = false) {
    const [value, setValue] = useState(initial);

    const toggle = useCallback(() => setValue(v => !v), []);
    const setTrue = useCallback(() => setValue(true), []);
    const setFalse = useCallback(() => setValue(false), []);

    return { value, toggle, setTrue, setFalse };
}

// ============================================
// Hook 4: useDebounce
// ============================================

function useDebounce(value, delay = 300) {
    const [debouncedValue, setDebouncedValue] = useState(value);

    useEffect(() => {
        const timer = setTimeout(() => {
            setDebouncedValue(value);
        }, delay);

        return () => clearTimeout(timer);
    }, [value, delay]);

    return debouncedValue;
}

// ============================================
// Hook 5: useWindowSize
// ============================================

function useWindowSize() {
    const [size, setSize] = useState({
        width: window.innerWidth,
        height: window.innerHeight
    });

    useEffect(() => {
        const handleResize = () => {
            setSize({
                width: window.innerWidth,
                height: window.innerHeight
            });
        };

        window.addEventListener('resize', handleResize);
        return () => window.removeEventListener('resize', handleResize);
    }, []);

    return size;
}

// ============================================
// Hook 6: useClickOutside
// ============================================

function useClickOutside(ref, callback) {
    useEffect(() => {
        const handleClick = (event) => {
            if (ref.current && !ref.current.contains(event.target)) {
                callback();
            }
        };

        document.addEventListener('mousedown', handleClick);
        return () => document.removeEventListener('mousedown', handleClick);
    }, [ref, callback]);
}

// ============================================
// Hook 7: usePrevious
// ============================================

function usePrevious(value) {
    const ref = useRef();

    useEffect(() => {
        ref.current = value;
    }, [value]);

    return ref.current;
}

// ============================================
// Hook 8: useCounter
// ============================================

function useCounter(initial = 0, { min = -Infinity, max = Infinity, step = 1 } = {}) {
    const [count, setCount] = useState(initial);

    const increment = useCallback(() => {
        setCount(c => Math.min(c + step, max));
    }, [step, max]);

    const decrement = useCallback(() => {
        setCount(c => Math.max(c - step, min));
    }, [step, min]);

    const reset = useCallback(() => setCount(initial), [initial]);

    const set = useCallback((value) => {
        setCount(Math.min(Math.max(value, min), max));
    }, [min, max]);

    return { count, increment, decrement, reset, set };
}

// ============================================
// דוגמאות שימוש
// ============================================

function FetchDemo() {
    const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users?_limit=3');

    if (loading) return <p>⏳ טוען משתמשים...</p>;
    if (error) return <p>❌ שגיאה: {error}</p>;

    return (
        <div>
            <h3>useFetch</h3>
            <ul>
                {data?.map(user => (
                    <li key={user.id}>{user.name}</li>
                ))}
            </ul>
        </div>
    );
}

function LocalStorageDemo() {
    const [name, setName] = useLocalStorage('demo-name', '');
    const [count, setCount] = useLocalStorage('demo-count', 0);

    return (
        <div>
            <h3>useLocalStorage</h3>
            <p>הנתונים נשמרים גם אחרי רענון! 💾</p>
            <input
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="השם שלך"
            />
            <p>שלום, {name || 'אורח'}!</p>
            <button onClick={() => setCount(c => c + 1)}>
                ספירה: {count}
            </button>
        </div>
    );
}

function ToggleDemo() {
    const modal = useToggle(false);

    return (
        <div>
            <h3>useToggle</h3>
            <button onClick={modal.toggle}>
                {modal.value ? 'סגור מודל' : 'פתח מודל'}
            </button>

            {modal.value && (
                <div style={{
                    position: 'fixed',
                    top: '50%',
                    left: '50%',
                    transform: 'translate(-50%, -50%)',
                    padding: '20px',
                    backgroundColor: 'white',
                    boxShadow: '0 4px 20px rgba(0,0,0,0.3)',
                    zIndex: 1000
                }}>
                    <h4>מודל</h4>
                    <p>תוכן המודל</p>
                    <button onClick={modal.setFalse}>סגור</button>
                </div>
            )}
        </div>
    );
}

function DebounceDemo() {
    const [query, setQuery] = useState('');
    const debouncedQuery = useDebounce(query, 500);

    return (
        <div>
            <h3>useDebounce</h3>
            <input
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                placeholder="חפש..."
            />
            <p>הקלדת: {query}</p>
            <p>ערך debounced (500ms): {debouncedQuery}</p>
        </div>
    );
}

function WindowSizeDemo() {
    const { width, height } = useWindowSize();

    return (
        <div>
            <h3>useWindowSize</h3>
            <p>📐 גודל חלון: {width} × {height}</p>
            <p>מכשיר: {width < 768 ? '📱 מובייל' : '💻 דסקטופ'}</p>
        </div>
    );
}

function ClickOutsideDemo() {
    const [isOpen, setIsOpen] = useState(false);
    const dropdownRef = useRef(null);

    useClickOutside(dropdownRef, () => setIsOpen(false));

    return (
        <div>
            <h3>useClickOutside</h3>
            <div ref={dropdownRef} style={{ display: 'inline-block' }}>
                <button onClick={() => setIsOpen(!isOpen)}>
                    תפריט {isOpen ? '▲' : '▼'}
                </button>

                {isOpen && (
                    <ul style={{
                        position: 'absolute',
                        listStyle: 'none',
                        padding: '10px',
                        margin: 0,
                        backgroundColor: '#fff',
                        boxShadow: '0 2px 10px rgba(0,0,0,0.2)'
                    }}>
                        <li>אפשרות 1</li>
                        <li>אפשרות 2</li>
                        <li>אפשרות 3</li>
                    </ul>
                )}
            </div>
            <p>לחץ מחוץ לתפריט כדי לסגור</p>
        </div>
    );
}

function CounterDemo() {
    const counter = useCounter(0, { min: 0, max: 10, step: 1 });

    return (
        <div>
            <h3>useCounter</h3>
            <p>ספירה: {counter.count}</p>
            <button onClick={counter.decrement}>➖</button>
            <button onClick={counter.increment}>➕</button>
            <button onClick={counter.reset}>🔄</button>
            <p style={{ fontSize: '0.8rem' }}>מוגבל: 0-10</p>
        </div>
    );
}

// ============================================
// קומפוננטה ראשית
// ============================================

function App() {
    return (
        <div style={{ padding: '20px' }}>
            <h1>🪝 Custom Hooks</h1>

            <div style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
                gap: '20px'
            }}>
                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <FetchDemo />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <LocalStorageDemo />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <ToggleDemo />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <DebounceDemo />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <WindowSizeDemo />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <ClickOutsideDemo />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <CounterDemo />
                </section>
            </div>
        </div>
    );
}

export default App;
