import * as Sentry from '@sentry/react-native';
import React from 'react';
import { ScrollView, StyleSheet, Text, View } from 'react-native';
import { theme } from './theme';

interface Props {
  children: React.ReactNode;
  /** Opcjonalny tag wysyłany do Sentry — pomaga rozróżnić top-level boundary od lokalnych. */
  scope?: string;
}

interface State {
  error: Error | null;
  info: string | null;
}

export class ErrorBoundary extends React.Component<Props, State> {
  state: State = { error: null, info: null };

  static getDerivedStateFromError(error: Error): State {
    return { error, info: null };
  }

  componentDidCatch(error: Error, info: React.ErrorInfo): void {
    this.setState({ error, info: info.componentStack || null });
    // Sentry.wrap()-owy boundary łapie tylko jeśli root nie jest manuanle wrapped.
    // Dodajemy explicit capture żeby ten boundary też wysyłał — z tagiem `scope`
    // żebyśmy w UI Sentry odróżnili global crash od per-tab crash.
    Sentry.captureException(error, {
      tags: { boundary: this.props.scope || 'global' },
      contexts: { react: { componentStack: info.componentStack } },
    });
    // eslint-disable-next-line no-console
    console.error('App crashed:', error, info);
  }

  render() {
    if (this.state.error) {
      return (
        <ScrollView style={styles.container} contentContainerStyle={{ padding: 20 }}>
          <Text style={styles.title}>App crashed</Text>
          <Text style={styles.label}>Error</Text>
          <Text style={styles.body}>{this.state.error.name}: {this.state.error.message}</Text>
          {this.state.error.stack ? (
            <>
              <Text style={styles.label}>Stack</Text>
              <Text style={styles.code}>{this.state.error.stack}</Text>
            </>
          ) : null}
          {this.state.info ? (
            <>
              <Text style={styles.label}>Component stack</Text>
              <Text style={styles.code}>{this.state.info}</Text>
            </>
          ) : null}
        </ScrollView>
      );
    }
    return <>{this.props.children}</>;
  }
}

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: theme.bg },
  title: { color: theme.bad, fontSize: 24, fontWeight: '700', marginBottom: 16 },
  label: {
    color: theme.muted,
    fontSize: 12,
    textTransform: 'uppercase',
    letterSpacing: 0.6,
    marginTop: 16,
    marginBottom: 4,
  },
  body: { color: theme.fg, fontSize: 14 },
  code: {
    color: theme.fg,
    fontSize: 11,
    fontFamily: 'monospace',
  },
});
