/**
 * 15 - Performance Example
 * 
 * דוגמאות ל-React.memo, useMemo, useCallback
 * לאופטימיזציית ביצועים.
 */

import React, { useState, useMemo, useCallback, memo } from 'react';

// ============================================
// 1. React.memo - מניעת רינדורים מיותרים
// ============================================

// קומפוננטה רגילה
function RegularChild({ value }) {
    console.log('🔄 RegularChild rendered');
    return <p>Regular: {value}</p>;
}

// קומפוננטה memoized
const MemoizedChild = memo(function MemoizedChild({ value }) {
    console.log('✅ MemoizedChild rendered');
    return <p>Memoized: {value}</p>;
});

function MemoExample() {
    const [count, setCount] = useState(0);
    const [text, setText] = useState('');

    return (
        <div>
            <h3>React.memo</h3>
            <p>פתח את הקונסול וראה את ההבדל</p>

            <input
                value={text}
                onChange={(e) => setText(e.target.value)}
                placeholder="הקלד (לא משפיע על ילדים)..."
            />

            <button onClick={() => setCount(c => c + 1)}>
                Count: {count}
            </button>

            {/* שני הילדים מקבלים אותו value שלא משתנה */}
            <RegularChild value="קבוע" />
            <MemoizedChild value="קבוע" />

            <p style={{ fontSize: '0.8rem', color: '#666' }}>
                RegularChild מתרנדר בכל שינוי, MemoizedChild רק כש-value משתנה
            </p>
        </div>
    );
}

// ============================================
// 2. useMemo - שמירת ערך מחושב
// ============================================

function UseMemoExample() {
    const [numbers, setNumbers] = useState([1, 2, 3, 4, 5]);
    const [multiplier, setMultiplier] = useState(2);
    const [text, setText] = useState('');

    // ❌ ללא useMemo - מחושב בכל רינדור
    // const sum = numbers.reduce((a, b) => a + b, 0) * multiplier;

    // ✅ עם useMemo - מחושב רק כשהתלויות משתנות
    const expensiveSum = useMemo(() => {
        console.log('🔢 מחשב סכום...');
        // סימולציית חישוב כבד
        let result = 0;
        for (let i = 0; i < 1000000; i++) {
            result += numbers.reduce((a, b) => a + b, 0);
        }
        return (result / 1000000) * multiplier;
    }, [numbers, multiplier]);

    const addNumber = () => {
        setNumbers([...numbers, numbers.length + 1]);
    };

    return (
        <div>
            <h3>useMemo</h3>

            <p>מספרים: [{numbers.join(', ')}]</p>
            <button onClick={addNumber}>הוסף מספר</button>

            <div style={{ margin: '10px 0' }}>
                <label>
                    מכפיל: {multiplier}
                    <input
                        type="range"
                        min="1" max="10"
                        value={multiplier}
                        onChange={(e) => setMultiplier(Number(e.target.value))}
                    />
                </label>
            </div>

            <p>סכום × {multiplier} = <strong>{expensiveSum}</strong></p>

            <hr />

            <p>הקלדה (לא גורמת לחישוב מחדש):</p>
            <input
                value={text}
                onChange={(e) => setText(e.target.value)}
                placeholder="הקלד..."
            />
            <p>הקלדת: {text}</p>
        </div>
    );
}

// ============================================
// 3. useCallback - שמירת פונקציה
// ============================================

// ילד memoized שמקבל פונקציה
const ExpensiveButton = memo(function ExpensiveButton({ onClick, label }) {
    console.log(`🔘 Button "${label}" rendered`);
    return (
        <button onClick={onClick} style={{ margin: '5px' }}>
            {label}
        </button>
    );
});

function UseCallbackExample() {
    const [count, setCount] = useState(0);
    const [text, setText] = useState('');

    // ❌ ללא useCallback - פונקציה חדשה בכל רינדור
    const handleClickBad = () => {
        setCount(c => c + 1);
    };

    // ✅ עם useCallback - אותה פונקציה
    const handleClickGood = useCallback(() => {
        setCount(c => c + 1);
    }, []);

    const handleReset = useCallback(() => {
        setCount(0);
    }, []);

    return (
        <div>
            <h3>useCallback</h3>
            <p>Count: {count}</p>

            <p>כפתורים עם פונקציות:</p>

            {/* כפתור עם פונקציה חדשה - יתרנדר בכל פעם */}
            <ExpensiveButton onClick={handleClickBad} label="❌ ללא useCallback" />

            {/* כפתור עם פונקציה memoized - לא יתרנדר */}
            <ExpensiveButton onClick={handleClickGood} label="✅ עם useCallback" />

            <ExpensiveButton onClick={handleReset} label="🔄 אפס" />

            <hr />

            <p>הקלדה (גורמת לרינדור של הורה):</p>
            <input
                value={text}
                onChange={(e) => setText(e.target.value)}
                placeholder="הקלד..."
            />
        </div>
    );
}

// ============================================
// 4. דוגמה משולבת
// ============================================

const FilteredList = memo(function FilteredList({ items, filter }) {
    console.log('📋 FilteredList rendered');

    const filteredItems = useMemo(() => {
        console.log('🔍 Filtering...');
        return items.filter(item =>
            item.toLowerCase().includes(filter.toLowerCase())
        );
    }, [items, filter]);

    return (
        <ul>
            {filteredItems.length === 0 ? (
                <li>לא נמצאו תוצאות</li>
            ) : (
                filteredItems.map((item, i) => (
                    <li key={i}>{item}</li>
                ))
            )}
        </ul>
    );
});

function CombinedExample() {
    const [items] = useState([
        'תפוח', 'בננה', 'תפוז', 'אבטיח', 'ענבים',
        'תות', 'אפרסק', 'שזיף', 'מנגו', 'קיווי'
    ]);
    const [filter, setFilter] = useState('');
    const [count, setCount] = useState(0);

    const handleFilterChange = useCallback((e) => {
        setFilter(e.target.value);
    }, []);

    return (
        <div>
            <h3>דוגמה משולבת</h3>

            <input
                value={filter}
                onChange={handleFilterChange}
                placeholder="סנן פירות..."
            />

            <FilteredList items={items} filter={filter} />

            <hr />

            <button onClick={() => setCount(c => c + 1)}>
                Counter: {count}
            </button>
            <p style={{ fontSize: '0.8rem' }}>
                שינוי ה-counter לא גורם לחישוב הסינון מחדש
            </p>
        </div>
    );
}

// ============================================
// קומפוננטה ראשית
// ============================================

function App() {
    return (
        <div style={{ padding: '20px' }}>
            <h1>⚡ Performance Optimization</h1>
            <p>פתח את הקונסול כדי לראות מה מתרנדר!</p>

            <div style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
                gap: '20px'
            }}>
                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <MemoExample />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <UseMemoExample />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <UseCallbackExample />
                </section>

                <section style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>
                    <CombinedExample />
                </section>
            </div>
        </div>
    );
}

export default App;
