// test/widget/sos_screen_test.dart
//
// Widget tests untuk SosScreen — layar SOS tunanetra.
// Jalankan: flutter test test/widget/sos_screen_test.dart

// ignore_for_file: avoid_print

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

// ---------------------------------------------------------------------------
// Stubs / Models
// ---------------------------------------------------------------------------

enum SosTriggerType { voiceCommand, button, manual }

enum SosStatus { triggered, acknowledged, resolved }

class SosEvent {
  final int id;
  final SosTriggerType triggerType;
  final double? lat;
  final double? lng;
  final SosStatus status;
  final DateTime createdAt;
  final DateTime? acknowledgedAt;

  const SosEvent({
    required this.id,
    required this.triggerType,
    this.lat,
    this.lng,
    required this.status,
    required this.createdAt,
    this.acknowledgedAt,
  });
}

/// Stub SosScreen yang mereplikasi struktur UI asli
class _StubSosScreen extends StatefulWidget {
  final List<SosEvent> events;
  final bool isLoading;
  final String? errorMessage;
  final bool hasPairedGuardian;

  const _StubSosScreen({
    this.events = const [],
    this.isLoading = false,
    this.errorMessage,
    this.hasPairedGuardian = true,
  });

  @override
  State<_StubSosScreen> createState() => _StubSosScreenState();
}

class _StubSosScreenState extends State<_StubSosScreen> {
  late List<SosEvent> _events;
  bool _sending = false;
  String? _sendError;
  bool _sendSuccess = false;

  @override
  void initState() {
    super.initState();
    _events = List.from(widget.events);
  }

  Future<void> _sendSos() async {
    if (!widget.hasPairedGuardian) {
      setState(() => _sendError = 'Belum ada Guardian yang terhubung');
      return;
    }
    setState(() {
      _sending = true;
      _sendError = null;
      _sendSuccess = false;
    });
    await Future.delayed(const Duration(milliseconds: 100));
    if (mounted) {
      setState(() {
        _sending = false;
        _sendSuccess = true;
        _events = [
          SosEvent(
            id: _events.length + 1,
            triggerType: SosTriggerType.button,
            lat: -7.2575,
            lng: 112.7521,
            status: SosStatus.triggered,
            createdAt: DateTime.now(),
          ),
          ..._events,
        ];
      });
    }
  }

  String _statusLabel(SosStatus status) => switch (status) {
        SosStatus.triggered => 'Terkirim',
        SosStatus.acknowledged => 'Diakui Guardian',
        SosStatus.resolved => 'Selesai',
      };

  Color _statusColor(SosStatus status) => switch (status) {
        SosStatus.triggered => Colors.orange,
        SosStatus.acknowledged => Colors.blue,
        SosStatus.resolved => Colors.green,
      };

  String _triggerLabel(SosTriggerType type) => switch (type) {
        SosTriggerType.voiceCommand => 'Voice Command',
        SosTriggerType.button => 'Tombol SOS',
        SosTriggerType.manual => 'Manual',
      };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('SOS')),
      body: Column(
        children: [
          // Peringatan tidak ada guardian
          if (!widget.hasPairedGuardian)
            Container(
              key: const Key('no_guardian_banner'),
              width: double.infinity,
              padding: const EdgeInsets.all(12),
              color: Colors.orange.shade100,
              child: const Row(
                children: [
                  Icon(Icons.warning_amber, color: Colors.orange),
                  SizedBox(width: 8),
                  Expanded(
                    child: Text(
                      key: Key('no_guardian_text'),
                      'Belum ada Guardian terhubung. SOS tetap bisa dikirim.',
                      style: TextStyle(color: Colors.orange),
                    ),
                  ),
                ],
              ),
            ),

          // SOS button utama
          Padding(
            padding: const EdgeInsets.all(24),
            child: Column(
              children: [
                const Text(
                  'Tekan tombol di bawah untuk mengirim sinyal darurat',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 16),
                ),
                const SizedBox(height: 24),
                _sending
                    ? const CircularProgressIndicator(
                        key: Key('sending_indicator'))
                    : GestureDetector(
                        onTap: _sendSos,
                        child: Container(
                          key: const Key('sos_button'),
                          width: 140,
                          height: 140,
                          decoration: BoxDecoration(
                            color: Colors.red,
                            shape: BoxShape.circle,
                            boxShadow: [
                              BoxShadow(
                                color: Colors.red.withValues(alpha: 0.4),
                                blurRadius: 20,
                                spreadRadius: 4,
                              ),
                            ],
                          ),
                          child: const Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              Icon(Icons.sos, color: Colors.white, size: 48),
                              Text(
                                'SOS',
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 24,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                const SizedBox(height: 16),
                if (_sendSuccess)
                  Container(
                    key: const Key('send_success_banner'),
                    padding: const EdgeInsets.all(12),
                    decoration: BoxDecoration(
                      color: Colors.green.shade50,
                      borderRadius: BorderRadius.circular(8),
                      border: Border.all(color: Colors.green.shade200),
                    ),
                    child: const Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.check_circle, color: Colors.green),
                        SizedBox(width: 8),
                        Text(
                          key: Key('send_success_text'),
                          'SOS berhasil dikirim!',
                          style: TextStyle(
                              color: Colors.green, fontWeight: FontWeight.bold),
                        ),
                      ],
                    ),
                  ),
                if (_sendError != null)
                  Container(
                    key: const Key('send_error_banner'),
                    padding: const EdgeInsets.all(12),
                    decoration: BoxDecoration(
                      color: Colors.red.shade50,
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: Text(
                      key: const Key('send_error_text'),
                      _sendError!,
                      style: const TextStyle(color: Colors.red),
                      textAlign: TextAlign.center,
                    ),
                  ),
              ],
            ),
          ),

          // Riwayat SOS
          const Divider(height: 1),
          const Padding(
            padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
            child: Align(
              alignment: Alignment.centerLeft,
              child: Text(
                'Riwayat SOS',
                key: Key('history_title'),
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
              ),
            ),
          ),
          Expanded(
            child: widget.isLoading
                ? const Center(
                    child: CircularProgressIndicator(
                        key: Key('loading_indicator')))
                : widget.errorMessage != null
                    ? Center(
                        child: Text(
                          key: const Key('error_message'),
                          widget.errorMessage!,
                        ),
                      )
                    : _events.isEmpty
                        ? const Center(
                            child: Text(
                              key: Key('empty_history_text'),
                              'Tidak ada riwayat SOS',
                              style: TextStyle(color: Colors.grey),
                            ),
                          )
                        : ListView.builder(
                            key: const Key('history_list'),
                            padding: const EdgeInsets.symmetric(horizontal: 16),
                            itemCount: _events.length,
                            itemBuilder: (context, index) {
                              final event = _events[index];
                              return Card(
                                key: Key('sos_event_${event.id}'),
                                margin: const EdgeInsets.only(bottom: 8),
                                child: ListTile(
                                  leading: Icon(
                                    Icons.sos,
                                    key: Key('sos_icon_${event.id}'),
                                    color: Colors.red,
                                  ),
                                  title: Text(
                                    key: Key('sos_trigger_${event.id}'),
                                    _triggerLabel(event.triggerType),
                                  ),
                                  subtitle: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      if (event.lat != null &&
                                          event.lng != null)
                                        Text(
                                          key: Key('sos_location_${event.id}'),
                                          'Lat: ${event.lat!.toStringAsFixed(4)}, Lng: ${event.lng!.toStringAsFixed(4)}',
                                          style: const TextStyle(fontSize: 11),
                                        ),
                                    ],
                                  ),
                                  trailing: Container(
                                    key: Key('sos_status_${event.id}'),
                                    padding: const EdgeInsets.symmetric(
                                        horizontal: 8, vertical: 4),
                                    decoration: BoxDecoration(
                                      color: _statusColor(event.status),
                                      borderRadius: BorderRadius.circular(12),
                                    ),
                                    child: Text(
                                      _statusLabel(event.status),
                                      style: const TextStyle(
                                          color: Colors.white, fontSize: 11),
                                    ),
                                  ),
                                ),
                              );
                            },
                          ),
          ),
        ],
      ),
    );
  }
}

Widget makeTestable(Widget child) => MaterialApp(home: child);

// Fixtures
final _triggeredEvent = SosEvent(
  id: 1,
  triggerType: SosTriggerType.button,
  lat: -7.2575,
  lng: 112.7521,
  status: SosStatus.triggered,
  createdAt: DateTime(2025, 5, 10, 14, 0),
);

final _acknowledgedEvent = SosEvent(
  id: 2,
  triggerType: SosTriggerType.voiceCommand,
  lat: -7.2601,
  lng: 112.7510,
  status: SosStatus.acknowledged,
  createdAt: DateTime(2025, 5, 9, 10, 0),
  acknowledgedAt: DateTime(2025, 5, 9, 10, 5),
);

final _resolvedEvent = SosEvent(
  id: 3,
  triggerType: SosTriggerType.manual,
  status: SosStatus.resolved,
  createdAt: DateTime(2025, 5, 8, 8, 0),
);

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

void main() {
  group('SosScreen Widget Tests', () {
    // ── Rendering awal ─────────────────────────────────────────────────────

    group('Rendering awal', () {
      testWidgets('menampilkan AppBar dengan judul SOS', (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));
        expect(find.text('SOS'), findsAtLeastNWidgets(1));
      });

      testWidgets('menampilkan tombol SOS bulat merah besar', (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));
        expect(find.byKey(const Key('sos_button')), findsOneWidget);
      });

      testWidgets('menampilkan judul riwayat SOS', (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));
        expect(find.byKey(const Key('history_title')), findsOneWidget);
      });

      testWidgets('menampilkan teks instruksi darurat', (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));
        expect(
          find.textContaining('sinyal darurat'),
          findsOneWidget,
        );
      });

      testWidgets('tidak menampilkan success banner saat awal', (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));
        expect(find.byKey(const Key('send_success_banner')), findsNothing);
      });

      testWidgets('tidak menampilkan error banner saat awal', (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));
        expect(find.byKey(const Key('send_error_banner')), findsNothing);
      });
    });

    // ── Warning no guardian ───────────────────────────────────────────────

    group('Warning tidak ada Guardian', () {
      testWidgets('menampilkan banner warning saat belum ada guardian',
          (tester) async {
        await tester.pumpWidget(
          makeTestable(const _StubSosScreen(hasPairedGuardian: false)),
        );

        expect(find.byKey(const Key('no_guardian_banner')), findsOneWidget);
      });

      testWidgets('menampilkan teks warning dengan benar', (tester) async {
        await tester.pumpWidget(
          makeTestable(const _StubSosScreen(hasPairedGuardian: false)),
        );

        expect(find.byKey(const Key('no_guardian_text')), findsOneWidget);
      });

      testWidgets('tidak menampilkan banner warning saat guardian ada',
          (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));

        expect(find.byKey(const Key('no_guardian_banner')), findsNothing);
      });
    });

    // ── Send SOS ──────────────────────────────────────────────────────────

    group('Kirim SOS', () {
      testWidgets('tap tombol SOS menampilkan loading indicator',
          (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));

        await tester.tap(find.byKey(const Key('sos_button')));
        await tester.pump();

        expect(find.byKey(const Key('sending_indicator')), findsOneWidget);
      });

      testWidgets('setelah SOS terkirim, tampil success banner',
          (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));

        await tester.tap(find.byKey(const Key('sos_button')));
        await tester.pumpAndSettle();

        expect(find.byKey(const Key('send_success_banner')), findsOneWidget);
        expect(find.byKey(const Key('send_success_text')), findsOneWidget);
      });

      testWidgets('setelah SOS terkirim, muncul event baru di riwayat',
          (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));

        await tester.tap(find.byKey(const Key('sos_button')));
        await tester.pumpAndSettle();

        expect(find.byKey(const Key('history_list')), findsOneWidget);
      });

      testWidgets('SOS tanpa guardian menampilkan error message',
          (tester) async {
        await tester.pumpWidget(
          makeTestable(const _StubSosScreen(hasPairedGuardian: false)),
        );

        await tester.tap(find.byKey(const Key('sos_button')));
        await tester.pump();

        expect(find.byKey(const Key('send_error_banner')), findsOneWidget);
        expect(find.textContaining('Guardian'), findsAtLeastNWidgets(1));
      });
    });

    // ── Riwayat SOS ───────────────────────────────────────────────────────

    group('Riwayat SOS', () {
      testWidgets('menampilkan empty state saat tidak ada riwayat',
          (tester) async {
        await tester.pumpWidget(makeTestable(const _StubSosScreen()));

        expect(find.byKey(const Key('empty_history_text')), findsOneWidget);
      });

      testWidgets('menampilkan event dalam daftar riwayat', (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_triggeredEvent, _acknowledgedEvent]),
        ));

        expect(find.byKey(const Key('sos_event_1')), findsOneWidget);
        expect(find.byKey(const Key('sos_event_2')), findsOneWidget);
      });

      testWidgets('menampilkan tipe trigger dengan benar (Button)',
          (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_triggeredEvent]),
        ));

        expect(find.text('Tombol SOS'), findsOneWidget);
      });

      testWidgets('menampilkan tipe trigger dengan benar (Voice Command)',
          (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_acknowledgedEvent]),
        ));

        expect(find.text('Voice Command'), findsOneWidget);
      });

      testWidgets('menampilkan tipe trigger Manual dengan benar',
          (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_resolvedEvent]),
        ));

        expect(find.text('Manual'), findsOneWidget);
      });

      testWidgets('menampilkan status badge TRIGGERED berwarna orange',
          (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_triggeredEvent]),
        ));

        expect(find.byKey(const Key('sos_status_1')), findsOneWidget);
        expect(find.text('Terkirim'), findsOneWidget);
      });

      testWidgets('menampilkan status badge ACKNOWLEDGED berwarna biru',
          (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_acknowledgedEvent]),
        ));

        expect(find.text('Diakui Guardian'), findsOneWidget);
      });

      testWidgets('menampilkan status badge RESOLVED berwarna hijau',
          (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_resolvedEvent]),
        ));

        expect(find.text('Selesai'), findsOneWidget);
      });

      testWidgets('menampilkan koordinat GPS jika tersedia', (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_triggeredEvent]),
        ));

        expect(find.byKey(const Key('sos_location_1')), findsOneWidget);
        expect(find.textContaining('Lat:'), findsOneWidget);
        expect(find.textContaining('Lng:'), findsOneWidget);
      });

      testWidgets('tidak menampilkan koordinat jika null', (tester) async {
        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: [_resolvedEvent]),
        ));

        expect(find.byKey(const Key('sos_location_3')), findsNothing);
      });
    });

    // ── Loading & Error ───────────────────────────────────────────────────

    group('Loading dan error state', () {
      testWidgets('menampilkan loading di riwayat saat isLoading=true',
          (tester) async {
        await tester
            .pumpWidget(makeTestable(const _StubSosScreen(isLoading: true)));

        expect(find.byKey(const Key('loading_indicator')), findsOneWidget);
      });

      testWidgets('menampilkan pesan error di area riwayat', (tester) async {
        await tester.pumpWidget(makeTestable(
          const _StubSosScreen(errorMessage: 'Gagal memuat riwayat'),
        ));

        expect(find.byKey(const Key('error_message')), findsOneWidget);
      });
    });

    // ── Responsif ─────────────────────────────────────────────────────────

    group('Responsif', () {
      testWidgets('tidak overflow pada layar 360x640', (tester) async {
        tester.view.physicalSize = const Size(360, 640);
        tester.view.devicePixelRatio = 1.0;
        addTearDown(tester.view.resetPhysicalSize);

        await tester.pumpWidget(makeTestable(const _StubSosScreen()));

        expect(tester.takeException(), isNull);
      });

      testWidgets('tidak overflow saat menampilkan banyak event',
          (tester) async {
        final manyEvents = List.generate(
          20,
          (i) => SosEvent(
            id: i,
            triggerType: SosTriggerType.button,
            status: SosStatus.resolved,
            createdAt: DateTime(2025, 5, i + 1),
          ),
        );

        await tester.pumpWidget(makeTestable(
          _StubSosScreen(events: manyEvents),
        ));

        expect(tester.takeException(), isNull);
      });
    });
  });
}
