import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cloud_functions/cloud_functions.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';

/// Para onde o app aponta — **configuração, não código comentado**.
///
/// A regra é a mesma que já valia para o `API_URL`: trocar de ambiente é
/// compilar com outro `--dart-define`, nunca descomentar uma linha. Bloco
/// comentado é o jeito mais fácil de mandar para a loja um app apontando para o
/// emulador da máquina de alguém.
///
/// ```
/// # emulador local, do emulador Android (10.0.2.2 é o localhost da máquina)
/// flutter run --dart-define=FIREBASE_EMULADOR=true
///
/// # emulador local, de device físico na mesma rede
/// flutter run --dart-define=FIREBASE_EMULADOR=true \
///             --dart-define=FIREBASE_HOST=192.168.0.109
///
/// # projeto real
/// flutter run --dart-define=FIREBASE_PROJETO=bolao-raro-4382d \
///             --dart-define=FIREBASE_API_KEY=... \
///             --dart-define=FIREBASE_APP_ID=... \
///             --dart-define=FIREBASE_SENDER_ID=...
/// ```
abstract final class FirebaseConfig {
  /// Emulador ligado é **opt-in**. O padrão tem de ser o ambiente de verdade:
  /// se esquecer o define no build de release, o app fala com o servidor real —
  /// e não com um emulador que não existe no aparelho de ninguém.
  static const usarEmulador = bool.fromEnvironment('FIREBASE_EMULADOR');

  /// `10.0.2.2` é como o emulador Android alcança o localhost da máquina. Em
  /// device físico não existe: passe o IP da máquina na rede.
  static const host = String.fromEnvironment(
    'FIREBASE_HOST',
    defaultValue: '10.0.2.2',
  );

  /// O prefixo `demo-` é o que garante que o emulador **nunca** encoste em
  /// serviço cobrado, mesmo se alguém errar o endereço.
  static const projeto = String.fromEnvironment(
    'FIREBASE_PROJETO',
    defaultValue: 'demo-bolao',
  );

  static const regiao = 'southamerica-east1';

  /// Credenciais do projeto real, por define.
  ///
  /// Elas **não** são segredo — chave de API do Firebase é pública por
  /// natureza, quem protege os dados são as security rules. Ficam fora do
  /// código mesmo assim, para o repositório não amarrar o app a um projeto só.
  /// Contra o emulador, qualquer valor serve: ele não valida credencial.
  ///
  /// O padrão precisa **ter o formato exato de uma chave**: o SDK Android valida
  /// com `AIza` + 35 caracteres antes de qualquer chamada, e recusa com "Please
  /// set a valid API key" mesmo apontando para o emulador, que não valida chave
  /// nenhuma. Um caractere a mais e as Functions param. Descoberto em device —
  /// teste de widget nenhum sai da máquina.
  static const apiKey = String.fromEnvironment(
    'FIREBASE_API_KEY',
    defaultValue: 'AIzaEmuladorLocalSemProjetoReal00000000',
  );
  static const appId = String.fromEnvironment(
    'FIREBASE_APP_ID',
    defaultValue: '1:000000000000:android:0000000000000000',
  );
  static const senderId = String.fromEnvironment(
    'FIREBASE_SENDER_ID',
    defaultValue: '000000000000',
  );

  static FirebaseOptions get opcoes => FirebaseOptions(
    apiKey: apiKey,
    appId: appId,
    messagingSenderId: senderId,
    projectId: projeto,
  );
}

/// Sobe o Firebase e, quando pedido, aponta tudo para os emuladores.
///
/// Chamado uma vez no `main`. Falha aqui é falha de configuração, não de rede:
/// deixar passar em silêncio faria o app abrir e só quebrar na primeira leitura,
/// longe da causa.
Future<void> iniciarFirebase() async {
  await Firebase.initializeApp(options: FirebaseConfig.opcoes);

  // **O cache offline continua sendo o nosso, e só o nosso.**
  //
  // O Firestore traz persistência local própria, e ela é boa — mas ela responde
  // dado antigo **sem dizer que é antigo**. O app já tem um cache que grava a
  // idade junto e a exibe ("de 3 h atrás"), porque dado velho sem rótulo é lido
  // como dado de agora, e aí o participante briga com quem tem o número certo.
  //
  // Ter os dois seria ter duas respostas para a mesma pergunta, uma delas sem
  // rótulo. Desligar aqui é a decisão que `MG-7` pedia por escrito: um dono só
  // para o offline.
  FirebaseFirestore.instance.settings = const Settings(
    persistenceEnabled: false,
  );

  if (!FirebaseConfig.usarEmulador) return;

  final host = FirebaseConfig.host;
  FirebaseFirestore.instance.useFirestoreEmulator(host, 8080);
  await FirebaseAuth.instance.useAuthEmulator(host, 9099);
  FirebaseFunctions.instanceFor(
    region: FirebaseConfig.regiao,
  ).useFunctionsEmulator(host, 5001);
}
