/**
 * 13 - React Patterns Example
 * 
 * דוגמאות ל-HOC, Render Props, Error Boundaries
 */

import React, { useState, useEffect, Component } from 'react';

// ============================================
// 1. HOC - Higher Order Component
// ============================================

// HOC שמוסיף מצב טעינה
function withLoading(WrappedComponent) {
    return function WithLoadingComponent({ isLoading, ...props }) {
        if (isLoading) {
            return (
                <div style={{
                    padding: '20px',
                    textAlign: 'center',
                    color: '#666'
                }}>
                    ⏳ טוען...
                </div>
            );
        }
        return <WrappedComponent {...props} />;
    };
}

// HOC שמוסיף לוגים
function withLogger(WrappedComponent) {
    return function WithLoggerComponent(props) {
        useEffect(() => {
            console.log(`[${WrappedComponent.name}] Mounted with props:`, props);
            return () => console.log(`[${WrappedComponent.name}] Unmounted`);
        }, []);

        return <WrappedComponent {...props} />;
    };
}

// קומפוננטה רגילה
function UserList({ users }) {
    return (
        <ul>
            {users.map(user => (
                <li key={user.id}>{user.name}</li>
            ))}
        </ul>
    );
}

// קומפוננטה משופרת
const EnhancedUserList = withLoading(withLogger(UserList));

function HOCDemo() {
    const [users, setUsers] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        setTimeout(() => {
            setUsers([
                { id: 1, name: 'דני' },
                { id: 2, name: 'רונית' },
                { id: 3, name: 'משה' }
            ]);
            setLoading(false);
        }, 1500);
    }, []);

    return (
        <div>
            <h3>HOC - Higher Order Component</h3>
            <p>withLoading + withLogger</p>
            <EnhancedUserList isLoading={loading} users={users} />
        </div>
    );
}

// ============================================
// 2. Render Props
// ============================================

function MouseTracker({ children }) {
    const [position, setPosition] = useState({ x: 0, y: 0 });

    useEffect(() => {
        const handleMove = (e) => {
            setPosition({ x: e.clientX, y: e.clientY });
        };

        window.addEventListener('mousemove', handleMove);
        return () => window.removeEventListener('mousemove', handleMove);
    }, []);

    return children(position);
}

function Toggle({ children }) {
    const [isOn, setIsOn] = useState(false);

    return children({
        isOn,
        toggle: () => setIsOn(v => !v),
        setOn: () => setIsOn(true),
        setOff: () => setIsOn(false)
    });
}

function RenderPropsDemo() {
    return (
        <div>
            <h3>Render Props</h3>

            <h4>Mouse Tracker</h4>
            <MouseTracker>
                {({ x, y }) => (
                    <p>🖱️ מיקום: {x}, {y}</p>
                )}
            </MouseTracker>

            <h4>Toggle</h4>
            <Toggle>
                {({ isOn, toggle }) => (
                    <div>
                        <button onClick={toggle}>
                            {isOn ? '🔵 ON' : '⚪ OFF'}
                        </button>
                        {isOn && <p>התוכן מוצג!</p>}
                    </div>
                )}
            </Toggle>
        </div>
    );
}

// ============================================
// 3. Error Boundary
// ============================================

class ErrorBoundary extends Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false, error: null };
    }

    static getDerivedStateFromError(error) {
        return { hasError: true, error };
    }

    componentDidCatch(error, info) {
        console.error('Error caught:', error);
        console.error('Component stack:', info.componentStack);
    }

    handleReset = () => {
        this.setState({ hasError: false, error: null });
    }

    render() {
        if (this.state.hasError) {
            return (
                <div style={{
                    padding: '20px',
                    backgroundColor: '#ffebee',
                    borderRadius: '8px',
                    border: '1px solid #ef9a9a'
                }}>
                    <h3>😰 משהו השתבש</h3>
                    <p>{this.state.error?.message}</p>
                    <button onClick={this.handleReset}>🔄 נסה שוב</button>
                </div>
            );
        }

        return this.props.children;
    }
}

// קומפוננטה שעלולה לזרוק שגיאה
function BuggyComponent({ shouldError }) {
    if (shouldError) {
        throw new Error('זו שגיאה מכוונת!');
    }

    return <p>✅ הקומפוננטה עובדת תקין</p>;
}

function ErrorBoundaryDemo() {
    const [shouldError, setShouldError] = useState(false);

    return (
        <div>
            <h3>Error Boundary</h3>
            <button onClick={() => setShouldError(true)}>
                💥 גרום לשגיאה
            </button>
            <button onClick={() => setShouldError(false)}>
                ✅ אפס
            </button>

            <ErrorBoundary>
                <BuggyComponent shouldError={shouldError} />
            </ErrorBoundary>
        </div>
    );
}

// ============================================
// 4. Compound Components Pattern
// ============================================

const TabsContext = React.createContext();

function Tabs({ children, defaultIndex = 0 }) {
    const [activeIndex, setActiveIndex] = useState(defaultIndex);

    return (
        <TabsContext.Provider value={{ activeIndex, setActiveIndex }}>
            <div className="tabs">{children}</div>
        </TabsContext.Provider>
    );
}

function TabList({ children }) {
    return <div className="tab-list" style={{ display: 'flex', gap: '5px' }}>{children}</div>;
}

function Tab({ children, index }) {
    const { activeIndex, setActiveIndex } = React.useContext(TabsContext);

    return (
        <button
            onClick={() => setActiveIndex(index)}
            style={{
                padding: '10px 20px',
                backgroundColor: activeIndex === index ? '#3498db' : '#ecf0f1',
                color: activeIndex === index ? 'white' : 'black',
                border: 'none',
                cursor: 'pointer'
            }}
        >
            {children}
        </button>
    );
}

function TabPanels({ children }) {
    const { activeIndex } = React.useContext(TabsContext);
    return <div className="tab-panels">{React.Children.toArray(children)[activeIndex]}</div>;
}

function TabPanel({ children }) {
    return <div className="tab-panel" style={{ padding: '20px' }}>{children}</div>;
}

function CompoundComponentsDemo() {
    return (
        <div>
            <h3>Compound Components</h3>

            <Tabs defaultIndex={0}>
                <TabList>
                    <Tab index={0}>🏠 בית</Tab>
                    <Tab index={1}>👤 פרופיל</Tab>
                    <Tab index={2}>⚙️ הגדרות</Tab>
                </TabList>

                <TabPanels>
                    <TabPanel>
                        <h4>דף הבית</h4>
                        <p>ברוכים הבאים!</p>
                    </TabPanel>
                    <TabPanel>
                        <h4>פרופיל</h4>
                        <p>פרטי המשתמש</p>
                    </TabPanel>
                    <TabPanel>
                        <h4>הגדרות</h4>
                        <p>הגדרות מערכת</p>
                    </TabPanel>
                </TabPanels>
            </Tabs>
        </div>
    );
}

// ============================================
// קומפוננטה ראשית
// ============================================

function App() {
    return (
        <div style={{ padding: '20px' }}>
            <h1>🎨 React Patterns</h1>

            <section style={{ marginBottom: '30px', padding: '15px', border: '1px solid #ddd' }}>
                <HOCDemo />
            </section>

            <section style={{ marginBottom: '30px', padding: '15px', border: '1px solid #ddd' }}>
                <RenderPropsDemo />
            </section>

            <section style={{ marginBottom: '30px', padding: '15px', border: '1px solid #ddd' }}>
                <ErrorBoundaryDemo />
            </section>

            <section style={{ marginBottom: '30px', padding: '15px', border: '1px solid #ddd' }}>
                <CompoundComponentsDemo />
            </section>
        </div>
    );
}

export default App;
