// integration_test/flow_2_walkguide_start_stop_sos_test.dart
//
// E2E Flow 2: Login → WalkGuide → Start → Stop → SOS
//
// Alur yang diuji:
//   1. Login berhasil → Dashboard
//   2. Tap tombol WalkGuide → layar WalkGuide terbuka
//   3. Tap "Mulai WalkGuide" → status berubah menjadi AKTIF
//   4. Banner obstacle terdeteksi muncul
//   5. Tap "Berhenti WalkGuide" → status kembali TIDAK AKTIF
//   6. Tap tombol SOS → konfirmasi dialog muncul
//   7. Konfirmasi SOS → status SOS TERKIRIM tampil
//
// Jalankan:
//   flutter test integration_test/flow_2_walkguide_start_stop_sos_test.dart

// ignore_for_file: avoid_print

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

// ─── Fake Credentials ────────────────────────────────────────────────────────

const _kEmail = 'user@walkguide.test';
const _kPassword = 'Password123!';

// ─── Stub State ──────────────────────────────────────────────────────────────

enum _WalkGuideStatus { idle, active }

enum _SosStatus { none, triggered }

class _AppState extends ChangeNotifier {
  bool _loggedIn = false;
  String _currentScreen = 'login'; // login | dashboard | walkguide | sos
  _WalkGuideStatus _walkGuideStatus = _WalkGuideStatus.idle;
  _SosStatus _sosStatus = _SosStatus.none;
  List<String> _detectedObstacles = [];

  bool get loggedIn => _loggedIn;
  String get currentScreen => _currentScreen;
  _WalkGuideStatus get walkGuideStatus => _walkGuideStatus;
  _SosStatus get sosStatus => _sosStatus;
  List<String> get detectedObstacles => _detectedObstacles;

  Future<bool> login(String email, String password) async {
    await Future.delayed(const Duration(milliseconds: 150));
    if (email == _kEmail && password == _kPassword) {
      _loggedIn = true;
      _currentScreen = 'dashboard';
      notifyListeners();
      return true;
    }
    return false;
  }

  void openWalkGuide() {
    _currentScreen = 'walkguide';
    notifyListeners();
  }

  Future<void> startWalkGuide() async {
    _walkGuideStatus = _WalkGuideStatus.active;
    notifyListeners();
    // Simulasi obstacle terdeteksi setelah 300ms
    await Future.delayed(const Duration(milliseconds: 300));
    _detectedObstacles = ['person (87%)', 'motorcycle (72%)'];
    notifyListeners();
  }

  void stopWalkGuide() {
    _walkGuideStatus = _WalkGuideStatus.idle;
    _detectedObstacles = [];
    notifyListeners();
  }

  void openSos() {
    _currentScreen = 'sos';
    notifyListeners();
  }

  Future<void> sendSos() async {
    await Future.delayed(const Duration(milliseconds: 150));
    _sosStatus = _SosStatus.triggered;
    notifyListeners();
  }

  void goBack() {
    if (_currentScreen == 'walkguide' || _currentScreen == 'sos') {
      _currentScreen = 'dashboard';
      notifyListeners();
    }
  }
}

// ─── Stub App ─────────────────────────────────────────────────────────────────

class _StubApp extends StatefulWidget {
  const _StubApp();

  @override
  State<_StubApp> createState() => _StubAppState();
}

class _StubAppState extends State<_StubApp> {
  final _state = _AppState();

  @override
  void dispose() {
    _state.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'WalkGuide Test',
      home: ListenableBuilder(
        listenable: _state,
        builder: (context, _) {
          switch (_state.currentScreen) {
            case 'walkguide':
              return _WalkGuideScreen(state: _state);
            case 'sos':
              return _SosScreen(state: _state);
            case 'dashboard':
              return _DashboardScreen(state: _state);
            default:
              return _LoginScreen(state: _state);
          }
        },
      ),
    );
  }
}

// ─── Login Screen ─────────────────────────────────────────────────────────────

class _LoginScreen extends StatefulWidget {
  final _AppState state;
  const _LoginScreen({required this.state});

  @override
  State<_LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<_LoginScreen> {
  final _emailCtrl = TextEditingController();
  final _passwordCtrl = TextEditingController();
  bool _loading = false;
  String? _error;

  @override
  void dispose() {
    _emailCtrl.dispose();
    _passwordCtrl.dispose();
    super.dispose();
  }

  Future<void> _submit() async {
    setState(() {
      _loading = true;
      _error = null;
    });
    final ok = await widget.state
        .login(_emailCtrl.text.trim(), _passwordCtrl.text.trim());
    if (!ok && mounted) {
      setState(() {
        _loading = false;
        _error = 'Credentials tidak valid';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(children: [
          TextField(
            key: const Key('emailField'),
            controller: _emailCtrl,
            decoration: const InputDecoration(labelText: 'Email'),
          ),
          const SizedBox(height: 12),
          TextField(
            key: const Key('passwordField'),
            controller: _passwordCtrl,
            obscureText: true,
            decoration: const InputDecoration(labelText: 'Password'),
          ),
          const SizedBox(height: 24),
          if (_error != null)
            Text(_error!, style: const TextStyle(color: Colors.red)),
          if (_loading)
            const CircularProgressIndicator()
          else
            ElevatedButton(
              key: const Key('loginButton'),
              onPressed: _submit,
              child: const Text('Login'),
            ),
        ]),
      ),
    );
  }
}

// ─── Dashboard Screen ─────────────────────────────────────────────────────────

class _DashboardScreen extends StatelessWidget {
  final _AppState state;
  const _DashboardScreen({required this.state});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Dashboard')),
      body: Center(
        child: Column(mainAxisSize: MainAxisSize.min, children: [
          ElevatedButton(
            key: const Key('openWalkGuideButton'),
            onPressed: state.openWalkGuide,
            child: const Text('Buka WalkGuide'),
          ),
          const SizedBox(height: 12),
          ElevatedButton(
            key: const Key('openSosButton'),
            onPressed: state.openSos,
            child: const Text('SOS'),
          ),
        ]),
      ),
    );
  }
}

// ─── WalkGuide Screen ─────────────────────────────────────────────────────────

class _WalkGuideScreen extends StatelessWidget {
  final _AppState state;
  const _WalkGuideScreen({required this.state});

  @override
  Widget build(BuildContext context) {
    final isActive = state.walkGuideStatus == _WalkGuideStatus.active;
    return Scaffold(
      appBar: AppBar(
        title: const Text('WalkGuide'),
        leading: IconButton(
          key: const Key('backButton'),
          icon: const Icon(Icons.arrow_back),
          onPressed: state.goBack,
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(mainAxisSize: MainAxisSize.min, children: [
          // Status badge
          Container(
            key: const Key('walkGuideStatusBadge'),
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
            decoration: BoxDecoration(
              color: isActive ? Colors.green : Colors.grey,
              borderRadius: BorderRadius.circular(20),
            ),
            child: Text(
              isActive ? 'WalkGuide AKTIF' : 'WalkGuide TIDAK AKTIF',
              style: const TextStyle(
                  color: Colors.white, fontWeight: FontWeight.bold),
            ),
          ),
          const SizedBox(height: 24),

          // Obstacle list
          if (state.detectedObstacles.isNotEmpty)
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  'Obstacle Terdeteksi:',
                  key: Key('obstacleHeader'),
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
                ...state.detectedObstacles.map((obs) => Text(
                      obs,
                      key: Key('obstacle_$obs'),
                    )),
                const SizedBox(height: 16),
              ],
            ),

          // Start / Stop button
          if (!isActive)
            ElevatedButton(
              key: const Key('startWalkGuideButton'),
              style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
              onPressed: state.startWalkGuide,
              child: const Text('Mulai WalkGuide'),
            )
          else
            ElevatedButton(
              key: const Key('stopWalkGuideButton'),
              style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
              onPressed: state.stopWalkGuide,
              child: const Text('Berhenti WalkGuide'),
            ),
          const SizedBox(height: 16),

          // SOS button
          OutlinedButton.icon(
            key: const Key('sosShortcutButton'),
            icon: const Icon(Icons.warning_amber, color: Colors.red),
            label: const Text('SOS', style: TextStyle(color: Colors.red)),
            onPressed: state.openSos,
          ),
        ]),
      ),
    );
  }
}

// ─── SOS Screen ───────────────────────────────────────────────────────────────

class _SosScreen extends StatelessWidget {
  final _AppState state;
  const _SosScreen({required this.state});

  @override
  Widget build(BuildContext context) {
    final sent = state.sosStatus == _SosStatus.triggered;
    return Scaffold(
      appBar: AppBar(
        title: const Text('SOS Darurat'),
        leading: IconButton(
          key: const Key('sosBackButton'),
          icon: const Icon(Icons.arrow_back),
          onPressed: state.goBack,
        ),
      ),
      body: Center(
        child: Column(mainAxisSize: MainAxisSize.min, children: [
          if (sent)
            const Text(
              'SOS TERKIRIM',
              key: Key('sosSentLabel'),
              style: TextStyle(
                fontSize: 24,
                color: Colors.red,
                fontWeight: FontWeight.bold,
              ),
            )
          else ...[
            const Text(
              'Tekan tombol SOS untuk mengirim bantuan darurat',
              key: Key('sosInstruction'),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              key: const Key('sendSosButton'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.red,
                padding:
                    const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
              ),
              onPressed: () async {
                // Tampilkan dialog konfirmasi
                final confirmed = await showDialog<bool>(
                  context: context,
                  builder: (_) => AlertDialog(
                    title: const Text('Konfirmasi SOS'),
                    content: const Text('Kirim sinyal SOS ke Guardian?'),
                    actions: [
                      TextButton(
                        key: const Key('cancelSosButton'),
                        onPressed: () => Navigator.pop(context, false),
                        child: const Text('Batal'),
                      ),
                      TextButton(
                        key: const Key('confirmSosButton'),
                        onPressed: () => Navigator.pop(context, true),
                        child: const Text('Ya, Kirim SOS'),
                      ),
                    ],
                  ),
                );
                if (confirmed == true) {
                  await state.sendSos();
                }
              },
              child: const Text(
                'KIRIM SOS',
                style: TextStyle(fontSize: 20, color: Colors.white),
              ),
            ),
          ],
        ]),
      ),
    );
  }
}

// ─── Tests ────────────────────────────────────────────────────────────────────

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  group('Flow 2 — Login → WalkGuide → Start → Stop → SOS', () {
    /// Helper: login dan buka WalkGuide screen
    Future<void> loginAndOpenWalkGuide(WidgetTester tester) async {
      await tester.pumpWidget(const _StubApp());
      await tester.pumpAndSettle();

      await tester.enterText(find.byKey(const Key('emailField')), _kEmail);
      await tester.enterText(
          find.byKey(const Key('passwordField')), _kPassword);
      await tester.tap(find.byKey(const Key('loginButton')));
      await tester.pumpAndSettle();

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

    testWidgets(
      '2.1  WalkGuide screen tampil setelah login dan tap tombol WalkGuide',
      (tester) async {
        await loginAndOpenWalkGuide(tester);

        expect(find.text('WalkGuide'), findsOneWidget,
            reason: 'Harus masuk ke WalkGuide screen');
        expect(find.byKey(const Key('walkGuideStatusBadge')), findsOneWidget);
        expect(find.text('WalkGuide TIDAK AKTIF'), findsOneWidget,
            reason: 'Status awal harus TIDAK AKTIF');

        print(
            '[PASS] 2.1  WalkGuide screen tampil dengan status awal TIDAK AKTIF');
      },
    );

    testWidgets(
      '2.2  Tap "Mulai WalkGuide" → status berubah menjadi AKTIF',
      (tester) async {
        await loginAndOpenWalkGuide(tester);

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

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

        expect(find.text('WalkGuide AKTIF'), findsOneWidget,
            reason: 'Status harus AKTIF setelah tombol ditekan');
        expect(find.byKey(const Key('stopWalkGuideButton')), findsOneWidget,
            reason: 'Tombol Stop harus muncul menggantikan tombol Start');

        print('[PASS] 2.2  Mulai WalkGuide → status AKTIF');
      },
    );

    testWidgets(
      '2.3  Obstacle terdeteksi tampil di layar saat WalkGuide aktif',
      (tester) async {
        await loginAndOpenWalkGuide(tester);
        await tester.tap(find.byKey(const Key('startWalkGuideButton')));
        await tester.pumpAndSettle();

        // Tunggu simulasi obstacle (300ms delay di stub)
        await tester.pump(const Duration(milliseconds: 400));
        await tester.pumpAndSettle();

        expect(find.byKey(const Key('obstacleHeader')), findsOneWidget,
            reason: 'Header obstacle harus muncul saat ada obstacle');

        print('[PASS] 2.3  Obstacle terdeteksi ditampilkan di layar');
      },
    );

    testWidgets(
      '2.4  Tap "Berhenti WalkGuide" → status kembali TIDAK AKTIF & obstacle hilang',
      (tester) async {
        await loginAndOpenWalkGuide(tester);

        // Start
        await tester.tap(find.byKey(const Key('startWalkGuideButton')));
        await tester.pumpAndSettle();
        await tester.pump(const Duration(milliseconds: 400));
        await tester.pumpAndSettle();
        expect(find.text('WalkGuide AKTIF'), findsOneWidget);

        // Stop
        await tester.tap(find.byKey(const Key('stopWalkGuideButton')));
        await tester.pumpAndSettle();

        expect(find.text('WalkGuide TIDAK AKTIF'), findsOneWidget,
            reason: 'Status harus kembali TIDAK AKTIF');
        expect(find.byKey(const Key('obstacleHeader')), findsNothing,
            reason: 'Daftar obstacle harus hilang setelah stop');
        expect(find.byKey(const Key('startWalkGuideButton')), findsOneWidget,
            reason: 'Tombol Start harus muncul kembali');

        print(
            '[PASS] 2.4  Stop WalkGuide → status TIDAK AKTIF & obstacle hilang');
      },
    );

    testWidgets(
      '2.5  Tap tombol SOS dari WalkGuide screen → SOS screen terbuka',
      (tester) async {
        await loginAndOpenWalkGuide(tester);

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

        expect(find.text('SOS Darurat'), findsOneWidget,
            reason: 'Harus berpindah ke SOS screen');
        expect(find.byKey(const Key('sendSosButton')), findsOneWidget);

        print('[PASS] 2.5  Tombol SOS dari WalkGuide → SOS screen terbuka');
      },
    );

    testWidgets(
      '2.6  Konfirmasi SOS → SOS terkirim dan label "SOS TERKIRIM" muncul',
      (tester) async {
        await loginAndOpenWalkGuide(tester);
        await tester.tap(find.byKey(const Key('sosShortcutButton')));
        await tester.pumpAndSettle();

        // Tap Send SOS button
        await tester.tap(find.byKey(const Key('sendSosButton')));
        await tester.pumpAndSettle();

        // Dialog konfirmasi muncul
        expect(find.text('Konfirmasi SOS'), findsOneWidget,
            reason: 'Dialog konfirmasi harus muncul');
        expect(find.byKey(const Key('confirmSosButton')), findsOneWidget);
        expect(find.byKey(const Key('cancelSosButton')), findsOneWidget);

        // Konfirmasi
        await tester.tap(find.byKey(const Key('confirmSosButton')));
        await tester.pumpAndSettle();

        expect(find.byKey(const Key('sosSentLabel')), findsOneWidget,
            reason: '"SOS TERKIRIM" harus tampil setelah konfirmasi');
        expect(find.text('SOS TERKIRIM'), findsOneWidget);
        // Tombol send tidak lagi tampil setelah SOS terkirim
        expect(find.byKey(const Key('sendSosButton')), findsNothing,
            reason: 'Tombol KIRIM SOS tidak boleh tampil setelah SOS terkirim');

        print('[PASS] 2.6  Konfirmasi SOS → "SOS TERKIRIM" muncul');
      },
    );

    testWidgets(
      '2.7  Batal konfirmasi SOS → SOS tidak terkirim, screen tetap sama',
      (tester) async {
        await loginAndOpenWalkGuide(tester);
        await tester.tap(find.byKey(const Key('sosShortcutButton')));
        await tester.pumpAndSettle();

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

        // Tap batal
        await tester.tap(find.byKey(const Key('cancelSosButton')));
        await tester.pumpAndSettle();

        expect(find.byKey(const Key('sosSentLabel')), findsNothing,
            reason: 'SOS tidak boleh terkirim jika user menekan Batal');
        expect(find.byKey(const Key('sendSosButton')), findsOneWidget,
            reason: 'Tombol KIRIM SOS harus masih ada');

        print('[PASS] 2.7  Batal konfirmasi → SOS tidak terkirim');
      },
    );
  });
}
