import React from "react";
import { Pressable, ScrollView, StyleSheet, Text } from "react-native";
import { recordCrash } from "../core/crashLog";

// Garde-fou de rendu : capture une erreur levee pendant le rendu d'un enfant
// (la ou setGlobalHandler ne voit rien) et affiche un ecran de repli propre au
// lieu d'un ecran blanc. L'incident est journalise via recordCrash, puis pousse
// au backend au prochain cycle de sync. Voir OBSERVABILITE_CRASH.md (approche A).

type Props = {
  children: React.ReactNode;
};

type State = {
  error: Error | null;
};

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

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

  componentDidCatch(error: Error, info: { componentStack?: string | null }): void {
    void recordCrash({
      kind: "render",
      message: error.message,
      stack: error.stack,
      componentStack: info.componentStack ?? undefined,
    });
  }

  private readonly handleRetry = (): void => {
    this.setState({ error: null });
  };

  render(): React.ReactNode {
    if (!this.state.error) {
      return this.props.children;
    }
    return (
      <ScrollView contentContainerStyle={styles.container}>
        <Text style={styles.title}>Une erreur est survenue</Text>
        <Text style={styles.message}>
          L'application a rencontre un probleme inattendu. Vous pouvez reessayer.
          L'incident a ete enregistre et sera transmis automatiquement.
        </Text>
        <Pressable
          accessibilityRole="button"
          onPress={this.handleRetry}
          style={({ pressed }) => [styles.button, pressed && styles.buttonPressed]}
        >
          <Text style={styles.buttonText}>Reessayer</Text>
        </Pressable>
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
    justifyContent: "center",
    padding: 24,
    gap: 16,
    backgroundColor: "#edf2f8",
  },
  title: {
    fontSize: 20,
    fontWeight: "700",
    color: "#16325c",
    textAlign: "center",
  },
  message: {
    fontSize: 15,
    lineHeight: 21,
    color: "#475569",
    textAlign: "center",
  },
  button: {
    backgroundColor: "#1e56a8",
    borderRadius: 12,
    paddingVertical: 14,
    alignItems: "center",
  },
  buttonPressed: {
    opacity: 0.7,
  },
  buttonText: {
    color: "#ffffff",
    fontSize: 16,
    fontWeight: "700",
  },
});
