import { Component, type ErrorInfo, type ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { Button, Card } from '@/shared/components/ui';

const Wrapper = styled.div`
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: ${({ theme }) => theme.spacing[6]};
  background: ${({ theme }) => theme.colors.surface};
`;

const Title = styled.h1`
  margin: 0 0 ${({ theme }) => theme.spacing[2]};
  font-size: ${({ theme }) => theme.typography.fontSize['2xl']};
`;

const Message = styled.p`
  margin: 0 0 ${({ theme }) => theme.spacing[4]};
  color: ${({ theme }) => theme.colors.text.secondary};
`;

function ErrorBoundaryFallback({ onReload }: { onReload: () => void }) {
  const { t } = useTranslation('common');

  return (
    <Wrapper>
      <Card variant="outlined" padding="lg">
        <Title>{t('errors.unexpected')}</Title>
        <Message>{t('errors.unexpectedHint')}</Message>
        <Button type="button" variant="primary" onClick={onReload}>
          {t('errors.reload')}
        </Button>
      </Card>
    </Wrapper>
  );
}

interface ErrorBoundaryProps {
  children: ReactNode;
}

interface ErrorBoundaryState {
  hasError: boolean;
}

export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  state: ErrorBoundaryState = { hasError: false };

  static getDerivedStateFromError(): ErrorBoundaryState {
    return { hasError: true };
  }

  componentDidCatch(error: Error, info: ErrorInfo): void {
    const requestId = sessionStorage.getItem('mvhd:last-request-id');
    const payload = {
      message: error.message,
      componentStack: info.componentStack,
      requestId,
    };
    if (import.meta.env.DEV) {
      console.error('Unhandled UI error', payload);
    } else {
      console.error('[mvhd-ui-error]', JSON.stringify(payload));
    }
  }

  private handleReload = () => {
    window.location.reload();
  };

  render() {
    if (this.state.hasError) {
      return <ErrorBoundaryFallback onReload={this.handleReload} />;
    }

    return this.props.children;
  }
}
