'use client';

import { Button } from '@/components/ui/button';
import { AlertTriangle, ChevronLeft, RefreshCw } from 'lucide-react';
import React, { Component, ReactNode } from 'react';

interface Props {
  children: ReactNode;
  fallback?: ReactNode;
  showBackButton?: boolean;
  backButtonText?: string;
  backButtonAction?: () => void;
}

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

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

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

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error('ErrorBoundary caught an error:', error, errorInfo);

    // シリアライゼーションエラーの詳細解析
    if (error.message.includes('Only plain objects')) {
      console.error('[SERIALIZATION_ERROR] シリアライゼーションエラーの詳細:');
      console.error('[SERIALIZATION_ERROR] Error message:', error.message);
      console.error('[SERIALIZATION_ERROR] Error stack:', error.stack);
      console.error('[SERIALIZATION_ERROR] Component stack:', errorInfo.componentStack);

      // エラーダイジェストが含まれている場合の解析
      if ('digest' in error) {
        console.error('[SERIALIZATION_ERROR] Error digest:', (error as Error & { digest?: string }).digest);
      }
    }
  }

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

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

      return (
        <div className="flex min-h-[400px] flex-col items-center justify-center p-8">
          <div className="mx-auto max-w-md text-center">
            <AlertTriangle className="mx-auto mb-4 h-16 w-16 text-red-500" />
            <h2 className="mb-2 text-2xl font-semibold text-gray-900">エラーが発生しました</h2>
            <p className="mb-6 text-gray-600">
              申し訳ございません。予期しないエラーが発生しました。
              {this.state.error?.message && <span className="mt-2 block text-sm text-gray-500">{this.state.error.message}</span>}
            </p>
            <div className="flex justify-center gap-3">
              {this.props.showBackButton && (
                <Button
                  onClick={this.props.backButtonAction}
                  className="flex h-10 min-w-[120px] cursor-pointer items-center justify-center gap-2 rounded-full border-[1px] border-[#CCCCCC] bg-white px-6 text-[12px] font-semibold text-[#212121] shadow-none hover:bg-[#EEEEEE] hover:text-[#212121]"
                >
                  <ChevronLeft className="h-4 w-4" />
                  {this.props.backButtonText || '戻る'}
                </Button>
              )}
              <Button
                onClick={this.handleReset}
                className="flex h-10 min-w-[120px] cursor-pointer items-center justify-center gap-2 rounded-full bg-[#212121] px-6 text-[12px] font-semibold text-white shadow-none hover:bg-[#212121E5]"
              >
                <RefreshCw className="h-4 w-4" />
                再試行
              </Button>
            </div>
          </div>
        </div>
      );
    }

    return this.props.children;
  }
}
