/**
 * エラーバウンダリ
 *
 * 子コンポーネントの描画時例外を捕捉し、管理画面全体が白画面になるのを防ぐ。
 * 例外時はエラーメッセージと再読み込みボタンを表示する。
 */
import { Component } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Button, Notice } from '@wordpress/components';

export default class ErrorBoundary extends Component {
	constructor( props ) {
		super( props );
		this.state = { hasError: false, message: '' };
	}

	static getDerivedStateFromError( error ) {
		return { hasError: true, message: error?.message || String( error ) };
	}

	componentDidCatch( error, info ) {
		// 開発・調査用にコンソールへ出力（本番でも害はない）。
		// eslint-disable-next-line no-console
		console.error( 'ConfManager admin render error:', error, info );
	}

	componentDidUpdate( prevProps ) {
		// ルート遷移などで resetKey が変わったらエラー状態を解除し、再描画を試みる。
		if ( this.state.hasError && prevProps.resetKey !== this.props.resetKey ) {
			this.setState( { hasError: false, message: '' } );
		}
	}

	render() {
		if ( this.state.hasError ) {
			return (
				<div style={ { padding: '16px' } }>
					<Notice status="error" isDismissible={ false }>
						<p>{ __( 'A display error occurred on this screen. Your data is safe; please reload.', 'conferencemanager' ) }</p>
						{ this.state.message && (
							<p style={ { fontSize: '12px', color: '#757575', wordBreak: 'break-all' } }>
								{ this.state.message }
							</p>
						) }
						<Button variant="primary" onClick={ () => window.location.reload() }>
							{ __( 'Reload', 'conferencemanager' ) }
						</Button>
					</Notice>
				</div>
			);
		}

		return this.props.children;
	}
}
