import 'dart:convert';

import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:pluriwave/servicios/servicio_radio.dart';

void main() {
  group('ServicioRadio retry + rotación', () {
    test(
      'reintenta con otro host cuando el primero falla y recupera en el segundo',
      () async {
        final hostsSolicitados = <String>[];
        final servicio = ServicioRadio(
          cliente: MockClient((request) async {
            hostsSolicitados.add(request.url.host);
            if (request.url.host == 'host-1.api.radio-browser.info') {
              return http.Response('fallo', 500);
            }
            return http.Response(
              jsonEncode([
                {
                  'stationuuid': 'uuid-ok',
                  'name': 'Radio Recuperada',
                  'url_resolved': 'https://stream.recuperada/audio',
                },
              ]),
              200,
              headers: {'content-type': 'application/json'},
            );
          }),
          servidores: const [
            'host-1.api.radio-browser.info',
            'host-2.api.radio-browser.info',
          ],
          maxIntentos: 3,
          retryDelay: Duration.zero,
        );

        final emisoras = await servicio.obtenerPopulares(limit: 1);

        expect(emisoras, hasLength(1));
        expect(emisoras.first.uuid, 'uuid-ok');
        expect(
          hostsSolicitados,
          equals([
            'host-1.api.radio-browser.info',
            'host-2.api.radio-browser.info',
          ]),
        );
      },
    );

    test('corta al llegar al tope de intentos y propaga error final', () async {
      var intentos = 0;
      final servicio = ServicioRadio(
        cliente: MockClient((request) async {
          intentos += 1;
          throw http.ClientException('sin red', request.url);
        }),
        servidores: const ['host-unico.api.radio-browser.info'],
        maxIntentos: 2,
        retryDelay: Duration.zero,
      );

      expect(
        () => servicio.obtenerPopulares(limit: 1),
        throwsA(isA<Exception>()),
      );
      expect(intentos, 2);
    });

    test('prioriza emisoras verificadas de mayor bitrate', () async {
      final servicio = ServicioRadio(
        cliente: MockClient((request) async {
          expect(request.url.queryParameters['order'], 'bitrate');
          expect(request.url.queryParameters['reverse'], 'true');
          return http.Response(
            jsonEncode([
              {
                'stationuuid': 'baja',
                'name': 'Baja',
                'url_resolved': 'https://stream.example/low',
                'bitrate': 64,
                'votes': 999,
              },
              {
                'stationuuid': 'alta',
                'name': 'Alta',
                'url_resolved': 'https://stream.example/high',
                'bitrate': 320,
                'votes': 1,
              },
            ]),
            200,
            headers: {'content-type': 'application/json'},
          );
        }),
        servidores: const ['host.api.radio-browser.info'],
        retryDelay: Duration.zero,
      );

      final emisoras = await servicio.buscar(nombre: 'radio');

      expect(emisoras.map((e) => e.uuid), equals(['alta', 'baja']));
    });
  });
}
