import React, { Component, ErrorInfo, ReactNode } from 'react';
import { AlertTriangle, RefreshCw, Home } from 'lucide-react';
import { Button } from '../ui/Button';

interface Props {
    children: ReactNode;
    fallback?: ReactNode;
}

interface State {
    hasError: boolean;
    error?: Error;
    errorInfo?: ErrorInfo;
}

export class ErrorBoundary extends Component<Props, State> {
    constructor(props: Props) {
        super(props);
        this.state = { hasError: false };
    }

    static getDerivedStateFromError(_: Error): State {
        return { hasError: true };
    }

    componentDidCatch(error: Error, errorInfo: ErrorInfo) {
        this.setState({
            error,
            errorInfo,
        });

        console.error('ErrorBoundary caught an error:', error, errorInfo);

        if (process.env.NODE_ENV === 'production') {
            this.logErrorToService(error, errorInfo);
        }
    }

    private logErrorToService = (error: Error, errorInfo: ErrorInfo) => {
        console.log('Error logged to service:', { error, errorInfo });
    };

    private handleRetry = () => {
        this.setState({ hasError: false, error: undefined, errorInfo: undefined });
    };

    private handleGoHome = () => {
        window.location.href = '/';
    };

    render() {
        if (this.state.hasError) {
            if (this.props.fallback) {
                return this.props.fallback;
            }

            return (
                <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center p-4">
                    <div className="max-w-md w-full bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 text-center">
                        <div className="mb-4">
                            <AlertTriangle className="h-16 w-16 text-red-500 mx-auto" />
                        </div>

                        <h1 className="text-xl font-bold text-gray-900 dark:text-gray-100 mb-2">
                            خطایی رخ داده است
                        </h1>

                        <p className="text-gray-600 dark:text-gray-400 mb-6">
                            متأسفانه مشکلی در برنامه رخ داده است. لطفاً دوباره تلاش کنید یا با پشتیبانی تماس بگیرید.
                        </p>

                        {process.env.NODE_ENV === 'development' && this.state.error && (
                            <details className="mb-6 text-left">
                                <summary className="cursor-pointer text-sm text-gray-500 dark:text-gray-400 mb-2">
                                    جزئیات خطا (فقط در حالت توسعه)
                                </summary>
                                <div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded p-3">
                                    <pre className="text-xs text-red-700 dark:text-red-300 overflow-auto">
                                        {this.state.error.toString()}
                                        {this.state.errorInfo?.componentStack}
                                    </pre>
                                </div>
                            </details>
                        )}

                        <div className="flex flex-col sm:flex-row gap-3">
                            <Button
                                onClick={this.handleRetry}
                                className="flex-1"
                                variant="primary"
                            >
                                <RefreshCw className="h-4 w-4 ml-2" />
                                تلاش دوباره
                            </Button>

                            <Button
                                onClick={this.handleGoHome}
                                className="flex-1"
                                variant="secondary"
                            >
                                <Home className="h-4 w-4 ml-2" />
                                بازگشت به خانه
                            </Button>
                        </div>
                    </div>
                </div>
            );
        }

        return this.props.children;
    }
}

export const withErrorBoundary = <P extends object>(
    Component: React.ComponentType<P>,
    fallback?: ReactNode
) => {
    const WrappedComponent = (props: P) => (
        <ErrorBoundary fallback={fallback}>
            <Component {...props} />
        </ErrorBoundary>
    );

    WrappedComponent.displayName = `withErrorBoundary(${Component.displayName || Component.name})`;

    return WrappedComponent;
}; 