import React, { useState } from "react";
import {
  Alert,
  Linking,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Constants from "expo-constants";
import * as MailComposer from "expo-mail-composer";
import { sendTestCrashReport } from "../../core/crashLog";

type Props = {
  appDisplayName: string;
  instanceUrl: string | null;
  tenantId: string | number | null;
  supportEmail: string | null;
  supportPhone: string | null;
};

const APP_VERSION = Constants.expoConfig?.version ?? "?";

// Bloc diagnostic injecte dans le corps du mail de support : permet de remonter
// la chaine technicien -> client -> prestataire sans avoir a redemander le
// contexte (instance, tenant, version, plateforme).
function buildDiagnostic(props: Readonly<Props>): string {
  const lines = [
    "",
    "----------",
    "Informations techniques (ne pas supprimer) :",
    `Application : ${props.appDisplayName} v${APP_VERSION}`,
    `Instance : ${props.instanceUrl || "-"}`,
    `Identifiant client : ${props.tenantId != null ? String(props.tenantId) : "-"}`,
    `Plateforme : ${Platform.OS} ${Platform.Version}`,
  ];
  return lines.join("\n");
}

// On NE PASSE PAS par Linking.canOpenURL : sur Android 11+ (API 30) la package
// visibility renvoie false pour les schemes mailto:/tel: tant que l'app ne
// declare pas une <queries> d'intent dans le manifeste, ce qui faisait croire
// a tort qu'"aucune application de messagerie n'est disponible". openURL lance
// l'activite directement (non soumise a la visibility) et ne rejette que si
// aucune app ne sait reellement ouvrir le lien : on n'alerte que dans ce cas.
async function openUrl(url: string, errorMessage: string): Promise<void> {
  try {
    await Linking.openURL(url);
  } catch {
    Alert.alert("Action impossible", errorMessage);
  }
}

const MAIL_UNAVAILABLE = "Aucune application de messagerie n'est disponible sur cet appareil.";

// Ouvre le mail de support en laissant le technicien CHOISIR sa messagerie.
// expo-mail-composer presente, sur Android, un selecteur d'application (Gmail /
// Outlook / ...) a chaque envoi : on ne subit plus l'app mail definie par
// defaut du systeme. Le sujet et le corps (diagnostic) sont transmis en clair,
// pas en URL-encode. Repli sur un lien mailto: si aucun composeur natif n'est
// disponible (composeAsync resolvant 'cancelled' = annulation normale, on ne
// retombe pas sur le repli dans ce cas).
async function composeSupportEmail(to: string, subject: string, body: string): Promise<void> {
  try {
    if (await MailComposer.isAvailableAsync()) {
      await MailComposer.composeAsync({ recipients: [to], subject, body });
      return;
    }
  } catch {
    // Composeur natif indisponible/en echec : on tente le repli mailto ci-dessous.
  }
  const mailto = `mailto:${to}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
  await openUrl(mailto, MAIL_UNAVAILABLE);
}

// Carte "Support" du dashboard coolcare, version mobile. Les coordonnees
// proviennent du branding tenant (mobile-config) : c'est le support de
// l'instance du technicien. En l'absence d'email/telephone configures cote
// backend, on retombe sur l'orientation vers l'administrateur web.
export default function SupportScreen({
  appDisplayName,
  instanceUrl,
  tenantId,
  supportEmail,
  supportPhone,
}: Readonly<Props>) {
  const insets = useSafeAreaInsets();

  // Diagnostic d'observabilite : volontairement cache (appui long sur la version)
  // pour qu'un technicien ne declenche pas un crash de test par megarde et ne
  // pollue pas la vue SuperAdmin. Reserve AUX BUILDS DE DEV (__DEV__) : en
  // production le bouton n'existe pas, aucun envoi de test possible. La chaine
  // de crash reporting ayant ete validee, on retest via un build dev au besoin.
  const diagnosticEnabled = __DEV__;
  const [diagnosticVisible, setDiagnosticVisible] = useState(false);
  const [sendingTestCrash, setSendingTestCrash] = useState(false);

  const onTestCrash = () => {
    if (sendingTestCrash) {
      return;
    }
    Alert.alert(
      "Tester la remontee de crash",
      "Un incident de TEST (clairement marque par le prefixe 🧪 [TEST]) va etre envoye au backend pour verifier la chaine d'observabilite. Il apparaitra dans la vue « Crashs mobile » du SuperAdmin et n'est PAS un vrai incident.",
      [
        { text: "Annuler", style: "cancel" },
        {
          text: "Envoyer le test",
          style: "destructive",
          onPress: () => {
            setSendingTestCrash(true);
            void sendTestCrashReport()
              .then((count) => {
                if (count > 0) {
                  Alert.alert(
                    "Test envoye ✅",
                    `${count} incident(s) transmis au backend. Ouvrez la vue « Crashs mobile » du SuperAdmin et reperez le prefixe 🧪 [TEST].`
                  );
                } else {
                  Alert.alert(
                    "Conserve en local ⏳",
                    "L'envoi n'a pas abouti (hors-ligne ou backend injoignable). L'incident de test reste stocke et sera reessaye automatiquement au prochain sync — exactement comme un vrai crash."
                  );
                }
              })
              .finally(() => setSendingTestCrash(false));
          },
        },
      ]
    );
  };

  const onEmail = () => {
    if (!supportEmail) {
      return;
    }
    const subject = `Support ${appDisplayName}`;
    const body = buildDiagnostic({
      appDisplayName,
      instanceUrl,
      tenantId,
      supportEmail,
      supportPhone,
    });
    void composeSupportEmail(supportEmail, subject, body);
  };

  const onCall = () => {
    if (!supportPhone) {
      return;
    }
    const cleaned = supportPhone.replace(/[^+\d]/g, "");
    void openUrl(
      `tel:${cleaned}`,
      "Impossible de lancer l'appel depuis cet appareil."
    );
  };

  const hasContact = Boolean(supportEmail || supportPhone);

  return (
    <ScrollView
      style={styles.screen}
      contentContainerStyle={[styles.content, { paddingBottom: insets.bottom + 24 }]}
      showsVerticalScrollIndicator={false}
    >
      <Text style={styles.heading}>A propos</Text>
      <Pressable
        accessibilityRole={diagnosticEnabled ? "button" : "text"}
        accessibilityLabel={`Application ${appDisplayName} version ${APP_VERSION}`}
        accessibilityHint={
          diagnosticEnabled ? "Appui long : afficher les outils de diagnostic" : undefined
        }
        delayLongPress={800}
        onLongPress={
          diagnosticEnabled ? () => setDiagnosticVisible((visible) => !visible) : undefined
        }
        style={styles.item}
      >
        <Text style={styles.itemLabel}>Application</Text>
        <Text style={styles.itemValue}>
          {appDisplayName} v{APP_VERSION}
        </Text>
      </Pressable>
      <View style={styles.item}>
        <Text style={styles.itemLabel}>Instance</Text>
        <Text style={styles.itemValue}>{instanceUrl || "-"}</Text>
      </View>
      {tenantId != null ? (
        <View style={styles.item}>
          <Text style={styles.itemLabel}>Identifiant client</Text>
          <Text style={styles.itemValue}>{String(tenantId)}</Text>
        </View>
      ) : null}

      {diagnosticEnabled && diagnosticVisible ? (
        <>
          <Text style={styles.heading}>Diagnostic</Text>
          <Pressable
            accessibilityRole="button"
            accessibilityLabel="Tester la remontee de crash vers le backend"
            disabled={sendingTestCrash}
            onPress={onTestCrash}
            style={({ pressed }) => [
              styles.item,
              styles.actionItem,
              styles.diagnosticItem,
              pressed && styles.itemPressed,
              sendingTestCrash && styles.itemPressed,
            ]}
          >
            <View style={styles.actionText}>
              <Text style={styles.itemLabel}>Observabilite</Text>
              <Text style={styles.diagnosticValue}>
                {sendingTestCrash ? "Envoi en cours…" : "Tester la remontee de crash"}
              </Text>
            </View>
            <Text style={styles.diagnosticChevron}>🧪 ›</Text>
          </Pressable>
          <Text style={styles.diagnosticHint}>
            Envoie un incident de TEST (prefixe 🧪 [TEST]) au backend pour verifier la chaine de
            crash reporting. Visible ensuite dans la vue « Crashs mobile » du SuperAdmin.
          </Text>
        </>
      ) : null}

      <Text style={styles.heading}>Besoin d'aide ?</Text>

      {supportEmail ? (
        <Pressable
          accessibilityRole="button"
          accessibilityLabel={`Ecrire au support : ${supportEmail}`}
          onPress={onEmail}
          style={({ pressed }) => [
            styles.item,
            styles.actionItem,
            pressed && styles.itemPressed,
          ]}
        >
          <View style={styles.actionText}>
            <Text style={styles.itemLabel}>Email support</Text>
            <Text style={styles.actionValue}>{supportEmail}</Text>
          </View>
          <Text style={styles.actionChevron}>Ecrire ›</Text>
        </Pressable>
      ) : null}

      {supportPhone ? (
        <Pressable
          accessibilityRole="button"
          accessibilityLabel={`Appeler le support : ${supportPhone}`}
          onPress={onCall}
          style={({ pressed }) => [
            styles.item,
            styles.actionItem,
            pressed && styles.itemPressed,
          ]}
        >
          <View style={styles.actionText}>
            <Text style={styles.itemLabel}>Telephone support</Text>
            <Text style={styles.actionValue}>{supportPhone}</Text>
          </View>
          <Text style={styles.actionChevron}>Appeler ›</Text>
        </Pressable>
      ) : null}

      <Text style={styles.paragraph}>
        {hasContact
          ? "Pour toute question sur une intervention ou un probleme technique, contactez le support de votre instance. Les informations techniques de l'application sont jointes automatiquement a votre email."
          : "Pour toute question sur une intervention ou un probleme technique, contactez l'administrateur de votre instance via l'application web. Les coordonnees de support dediees s'afficheront ici quand l'API mobile les fournira."}
      </Text>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  screen: {
    flex: 1,
    backgroundColor: "#edf2f8",
  },
  content: {
    padding: 16,
    gap: 10,
  },
  heading: {
    fontSize: 16,
    fontWeight: "700",
    color: "#16325c",
    marginTop: 4,
  },
  item: {
    backgroundColor: "#ffffff",
    borderWidth: 1,
    borderColor: "#e3ebf8",
    borderRadius: 12,
    padding: 14,
    gap: 4,
  },
  actionItem: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  itemPressed: {
    opacity: 0.6,
  },
  diagnosticItem: {
    borderColor: "#f0c36d",
    backgroundColor: "#fffaf0",
  },
  diagnosticValue: {
    fontSize: 15,
    color: "#9a6a00",
    fontWeight: "700",
  },
  diagnosticChevron: {
    color: "#9a6a00",
    fontWeight: "700",
    fontSize: 14,
    marginLeft: 12,
  },
  diagnosticHint: {
    color: "#8a6d3b",
    fontSize: 12,
    lineHeight: 17,
    paddingHorizontal: 2,
  },
  actionText: {
    flex: 1,
    gap: 4,
  },
  actionValue: {
    fontSize: 15,
    color: "#1e56a8",
    fontWeight: "700",
  },
  actionChevron: {
    color: "#1e56a8",
    fontWeight: "700",
    fontSize: 14,
    marginLeft: 12,
  },
  itemLabel: {
    fontSize: 11,
    color: "#66748f",
    fontWeight: "700",
  },
  itemValue: {
    fontSize: 15,
    color: "#1f2f4f",
    fontWeight: "700",
  },
  paragraph: {
    color: "#475569",
    fontSize: 14,
    lineHeight: 20,
  },
});
