// ============================================================
// examples_usage.dart
// Exemples d'utilisation du NymeaClient depuis etm_powersync_app
// ============================================================

import 'nymea_client.dart';

// UUIDs des stateTypes du chargeur mock (interface evcharger)
// À remplacer par les UUIDs réels de votre plugin d'intégration
const kStatePluggedIn  = '13f8f008-aa70-4772-9fb8-81a9674dd6ad';
const kStateCharging   = '63879844-6342-45ed-8e97-276e0f3092e5';
const kStatePower      = '13672543-9344-4d55-afd6-6393ae052f18';
const kStateMaxCurrent = 'e7566b5b-8258-486e-b0ed-42a1bee332d9';

// UUID fournisseurs spot market
const kProviderAwattarAustria = '5196b3cc-b2ee-46d6-b63a-7af2cf70ba67';
const kProviderAwattarGermany = '0ca6ad88-e243-438d-a0f8-986cecf61834';

// ─────────────────────────────────────────────────────────────
// EXEMPLE 1 — Connexion et authentification complète
// ─────────────────────────────────────────────────────────────
Future<NymeaClient?> example1_connect() async {
  print('\n=== Exemple 1 : Connexion à nymea ===');

  final client = NymeaClient(host: '192.168.1.100', port: 2222);

  try {
    await client.connect();

    // Première utilisation : créer l'utilisateur
    // await client.createUser('admin@etm.local', 'MonMotDePasse!');

    // Authentification (récupère un token)
    final token = await client.authenticate(
      'admin@etm.local',
      'MonMotDePasse!',
      'etm_powersync_app',
    );

    if (token == null) {
      print('Échec de l\'authentification');
      return null;
    }

    // Conserver le token en stockage sécurisé (FlutterSecureStorage, etc.)
    // await secureStorage.write(key: 'nymea_token', value: token);

    print('Connecté avec succès ! Token : ${token.substring(0, 8)}...');
    return client;
  } catch (e) {
    print('Erreur : $e');
    return null;
  }
}

// ─────────────────────────────────────────────────────────────
// EXEMPLE 2 — Récupérer tous les chargeurs VE du plugin
// ─────────────────────────────────────────────────────────────
Future<void> example2_getEvChargers(NymeaClient client) async {
  print('\n=== Exemple 2 : Récupération des chargeurs VE ===');

  // Récupère tous les Things qui implémentent l'interface "evcharger"
  final chargers = await client.getThingsByInterface('evcharger');

  print('${chargers.length} chargeur(s) trouvé(s) :');
  for (final charger in chargers) {
    print('  - ${charger['name']} (id: ${charger['id']})');
    print('    thingClassId: ${charger['thingClassId']}');
  }

  // Récupère les infos de smart charging via NymeaEnergy
  final chargingInfos = await client.getChargingInfos();
  print('\nInfos de charge :');
  for (final info in chargingInfos) {
    print('  Chargeur ${info.evChargerId}');
    print('    Mode       : ${info.chargingMode}');
    print('    État       : ${info.chargingState}');
    print('    Spot market: ${info.spotMarketChargingEnabled}');
    print('    Cible      : ${info.targetPercentage}%');
  }
}

// ─────────────────────────────────────────────────────────────
// EXEMPLE 3 — Lire un State spécifique (puissance actuelle)
// ─────────────────────────────────────────────────────────────
Future<void> example3_readState(NymeaClient client, String chargerId) async {
  print('\n=== Exemple 3 : Lecture d\'un State ===');

  // Lire si une voiture est branchée
  final pluggedIn = await client.getStateValue(chargerId, kStatePluggedIn);
  print('Voiture branchée : $pluggedIn');

  // Lire l'état de charge
  final charging = await client.getStateValue(chargerId, kStateCharging);
  print('En charge : $charging');

  // Lire la limite de courant max configurée par le SmartChargingManager
  final maxCurrent = await client.getStateValue(chargerId, kStateMaxCurrent);
  print('Courant max actuel : ${maxCurrent}A');

  // Lire la limite de phase via NymeaEnergy
  final phasePowerLimit = await client.getPhasePowerLimit();
  print('Limite par phase : ${phasePowerLimit}A');
}

// ─────────────────────────────────────────────────────────────
// EXEMPLE 4 — Exécuter des Actions et configurer le smart charging
// ─────────────────────────────────────────────────────────────
Future<void> example4_executeActions(NymeaClient client, String chargerId) async {
  print('\n=== Exemple 4 : Exécution d\'Actions ===');

  // 4a) Définir la limite de puissance par phase (25A)
  var result = await client.setPhasePowerLimit(25);
  print('SetPhasePowerLimit(25A) → $result');

  // 4b) Activer le mode Eco avec heure cible pour un chargeur
  result = await client.setChargingInfo(
    evChargerId: chargerId,
    mode: ChargingMode.ecoWithTargetTime,
    targetPercentage: 80,
    // Heure cible : demain matin 7h00
    endDateTime: DateTime.now()
        .copyWith(hour: 7, minute: 0, second: 0)
        .add(const Duration(days: 1))
        .toIso8601String(),
    spotMarketEnabled: true,
    dailySpotMarketPercentage: 80,
  );
  print('SetChargingInfo(EcoWithTargetTime) → $result');

  // 4c) Activer le spot market avec aWATTar Autriche
  result = await client.setSpotMarketConfiguration(
    enabled: true,
    providerId: kProviderAwattarAustria,
  );
  print('SetSpotMarketConfiguration(aWATTar AT) → $result');

  // 4d) Exécuter une Action native nymea sur un Thing
  //     (ex : forcer l'activation de la charge via le state writable "power")
  final actionResult = await client.executeAction(
    thingId: chargerId,
    actionTypeId: kStatePower,       // stateTypeId writable = actionTypeId implicite
    params: {kStatePower: true},     // activer la charge
  );
  print('ExecuteAction(power=true) → $actionResult');
}

// ─────────────────────────────────────────────────────────────
// EXEMPLE 5 — Écouter les Events en temps réel (WebSocket push)
// ─────────────────────────────────────────────────────────────
Future<void> example5_listenToEvents(NymeaClient client) async {
  print('\n=== Exemple 5 : Écoute des Events en temps réel ===');

  // S'abonner aux namespaces qui nous intéressent
  await client.subscribeToNotifications(['NymeaEnergy', 'Integrations']);

  // Écouter les changements de config de charge
  client.onChargingInfoChanged.listen((info) {
    print('[EVENT] ChargingInfoChanged:');
    print('  Chargeur : ${info.evChargerId}');
    print('  Nouvel état : ${info.chargingState}');
    print('  Mode : ${info.chargingMode}');
  });

  // Écouter les mises à jour des prix spot
  client.onSpotMarketScoreEntriesChanged.listen((entries) {
    print('[EVENT] SpotMarketScoreEntriesChanged: ${entries.length} créneaux');
    // Trouver le meilleur créneau (weighting le plus élevé)
    if (entries.isNotEmpty) {
      final best = entries.reduce((a, b) => a.weighting > b.weighting ? a : b);
      print('  Meilleur créneau: ${best.startDateTime} → ${best.endDateTime}');
      print('  Score: ${best.weighting.toStringAsFixed(2)} / Prix: ${best.value}€/MWh');
    }
  });

  // Écouter les changements de plannings de charge
  client.onChargingSchedulesChanged.listen((schedules) {
    print('[EVENT] ChargingSchedulesChanged: ${schedules.length} créneaux planifiés');
    for (final s in schedules) {
      print('  ${s['startDateTime']} → ${s['endDateTime']}');
    }
  });

  // Écouter toutes les notifications brutes (debug)
  client.notifications.listen((msg) {
    if (msg['notification']?.toString().startsWith('NymeaEnergy') ?? false) {
      // Log toutes les notifs NymeaEnergy
      print('[NOTIF] ${msg['notification']}');
    }
  });

  print('En écoute... (Ctrl+C pour arrêter)');
  // Dans une vraie app Flutter, cette écoute dure toute la vie du widget
  await Future.delayed(const Duration(minutes: 5));
}

// ─────────────────────────────────────────────────────────────
// EXEMPLE 6 — Consultation des prix spot + plannings
// ─────────────────────────────────────────────────────────────
Future<void> example6_spotMarket(NymeaClient client) async {
  print('\n=== Exemple 6 : Consultation du marché spot ===');

  // Fournisseurs disponibles
  final providers = await client.getAvailableSpotMarketProviders();
  print('Fournisseurs disponibles :');
  for (final p in providers) {
    print('  ${p['name']} (${p['id']}) — ${p['country']}');
  }

  // Scores de prix pondérés pour aujourd'hui
  final scores = await client.getSpotMarketScoreEntries();
  print('\n${scores.length} créneaux de prix disponibles :');

  // Trier par pondération (meilleur en premier)
  scores.sort((a, b) => b.weighting.compareTo(a.weighting));
  for (final s in scores.take(5)) {
    print(
      '  ${s.startDateTime.hour}h–${s.endDateTime.hour}h : '
      '${s.value.toStringAsFixed(1)}€/MWh '
      '(score: ${(s.weighting * 100).round()}%)',
    );
  }

  // Plannings de charge calculés par le SmartChargingManager
  final schedules = await client.getChargingSchedules();
  print('\nPlannings de charge :');
  for (final s in schedules) {
    print('  ${s['startDateTime']} → ${s['endDateTime']}');
    final action = s['action'] as Map<String, dynamic>?;
    if (action != null) {
      print('    Activé: ${action['chargingEnabled']} '
            'Courant: ${action['maxChargingCurrent']}A '
            'Phases: ${action['desiredPhaseCount']}');
    }
  }
}

// ─────────────────────────────────────────────────────────────
// MAIN — Démonstration complète
// ─────────────────────────────────────────────────────────────
Future<void> main() async {
  // 1. Connexion
  final client = await example1_connect();
  if (client == null) return;

  // 2. Récupération des chargeurs
  await example2_getEvChargers(client);

  // Pour les exemples suivants, on prend le premier chargeur trouvé
  final chargers = await client.getThingsByInterface('evcharger');
  if (chargers.isEmpty) {
    print('Aucun chargeur trouvé.');
    await client.disconnect();
    return;
  }
  final chargerId = chargers.first['id'] as String;

  // 3. Lecture d'un state
  await example3_readState(client, chargerId);

  // 4. Exécution d'actions
  await example4_executeActions(client, chargerId);

  // 5. Écoute événements
  // await example5_listenToEvents(client);

  // 6. Spot market
  await example6_spotMarket(client);

  await client.disconnect();
}
