// integration_test/flow_1_login_dashboard_logout_test.dart
//
// E2E Flow 1: Login → Dashboard → Logout
//
// Alur yang diuji:
//   1. User membuka app → tampil halaman Login
//   2. User mengisi email + password yang valid → tap Login
//   3. App berpindah ke Dashboard (HomeScreen)
//   4. Dashboard menampilkan nama user & status pairing
//   5. User tap Logout → kembali ke halaman Login
//
// Jalankan:
//   flutter test integration_test/flow_1_login_dashboard_logout_test.dart
//   atau dengan driver:
//   flutter drive \
//     --driver=test_driver/integration_test.dart \
//     --target=integration_test/flow_1_login_dashboard_logout_test.dart
//
// Catatan:
//   Test ini menggunakan StubApp yang self-contained (tanpa koneksi server
//   kampus) sehingga bisa dijalankan di CI maupun device fisik tanpa
//   internet. Untuk E2E full terhadap server live, ganti _StubApp dengan
//   import 'package:walkguide_app/main.dart' as app; dan gunakan Mockito
//   untuk mock ApiClient + SecureStorage.

// 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 _kValidEmail = 'user@walkguide.test';
const _kValidPassword = 'Password123!';
const _kDisplayName = 'Budi Tunanetra';

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

class _AuthState extends ChangeNotifier {
  String? _accessToken;
  String? _displayName;

  bool get isLoggedIn => _accessToken != null;
  String get displayName => _displayName ?? '';

  /// Simulasi login API call (200 ms delay).
  Future<bool> login(String email, String password) async {
    await Future.delayed(const Duration(milliseconds: 200));
    if (email == _kValidEmail && password == _kValidPassword) {
      _accessToken = 'fake-jwt-token';
      _displayName = _kDisplayName;
      notifyListeners();
      return true;
    }
    return false;
  }

  /// Simulasi logout.
  void logout() {
    _accessToken = null;
    _displayName = null;
    notifyListeners();
  }
}

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

class _StubApp extends StatefulWidget {
  const _StubApp();

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

class _StubAppState extends State<_StubApp> {
  final _auth = _AuthState();

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'WalkGuide Test',
      home: ListenableBuilder(
        listenable: _auth,
        builder: (context, _) {
          if (_auth.isLoggedIn) {
            return _DashboardScreen(auth: _auth);
          }
          return _LoginScreen(auth: _auth);
        },
      ),
    );
  }
}

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

class _LoginScreen extends StatefulWidget {
  final _AuthState auth;
  const _LoginScreen({required this.auth});

  @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.auth.login(
      _emailCtrl.text.trim(),
      _passwordCtrl.text.trim(),
    );
    if (!ok && mounted) {
      setState(() {
        _loading = false;
        _error = 'Email atau password salah';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('WalkGuide — 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!,
                key: const Key('loginError'),
                style: const TextStyle(color: Colors.red),
              ),
            if (_loading)
              const CircularProgressIndicator(key: Key('loginLoading'))
            else
              ElevatedButton(
                key: const Key('loginButton'),
                onPressed: _submit,
                child: const Text('Login'),
              ),
          ],
        ),
      ),
    );
  }
}

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

class _DashboardScreen extends StatelessWidget {
  final _AuthState auth;
  const _DashboardScreen({required this.auth});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Dashboard'),
        actions: [
          IconButton(
            key: const Key('logoutButton'),
            icon: const Icon(Icons.logout),
            tooltip: 'Logout',
            onPressed: auth.logout,
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(
              'Selamat datang, ${auth.displayName}',
              key: const Key('welcomeText'),
              style: const TextStyle(fontSize: 20),
            ),
            const SizedBox(height: 16),
            const Text(
              'Status Pairing: Belum terhubung',
              key: Key('pairingStatus'),
            ),
          ],
        ),
      ),
    );
  }
}

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

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  group('Flow 1 — Login → Dashboard → Logout', () {
    testWidgets(
      '1.1  Halaman Login tampil saat app pertama dibuka',
      (tester) async {
        await tester.pumpWidget(const _StubApp());
        await tester.pumpAndSettle();

        expect(find.text('WalkGuide — Login'), findsOneWidget,
            reason: 'AppBar harus menampilkan judul Login');
        expect(find.byKey(const Key('emailField')), findsOneWidget);
        expect(find.byKey(const Key('passwordField')), findsOneWidget);
        expect(find.byKey(const Key('loginButton')), findsOneWidget);

        print('[PASS] 1.1  Login screen tampil dengan semua field');
      },
    );

    testWidgets(
      '1.2  Login dengan credentials yang salah → tampil pesan error',
      (tester) async {
        await tester.pumpWidget(const _StubApp());
        await tester.pumpAndSettle();

        await tester.enterText(
            find.byKey(const Key('emailField')), 'wrong@email.com');
        await tester.enterText(
            find.byKey(const Key('passwordField')), 'wrongpass');
        await tester.tap(find.byKey(const Key('loginButton')));
        await tester.pumpAndSettle();

        expect(find.byKey(const Key('loginError')), findsOneWidget,
            reason: 'Error message harus muncul saat credentials salah');
        expect(find.text('WalkGuide — Login'), findsOneWidget,
            reason: 'Harus tetap di halaman Login');

        print('[PASS] 1.2  Error message tampil untuk credentials salah');
      },
    );

    testWidgets(
      '1.3  Login berhasil dengan credentials valid → pindah ke Dashboard',
      (tester) async {
        await tester.pumpWidget(const _StubApp());
        await tester.pumpAndSettle();

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

        expect(find.text('Dashboard'), findsOneWidget,
            reason: 'Setelah login berhasil harus tampil halaman Dashboard');
        expect(
          find.byKey(const Key('welcomeText')),
          findsOneWidget,
          reason: 'Pesan selamat datang harus muncul',
        );
        expect(
          find.textContaining(_kDisplayName),
          findsOneWidget,
          reason: 'Nama user harus ditampilkan di Dashboard',
        );

        print('[PASS] 1.3  Login berhasil → Dashboard tampil dengan nama user');
      },
    );

    testWidgets(
      '1.4  Dashboard menampilkan status pairing',
      (tester) async {
        await tester.pumpWidget(const _StubApp());
        await tester.pumpAndSettle();

        // Login
        await tester.enterText(
            find.byKey(const Key('emailField')), _kValidEmail);
        await tester.enterText(
            find.byKey(const Key('passwordField')), _kValidPassword);
        await tester.tap(find.byKey(const Key('loginButton')));
        await tester.pumpAndSettle();

        expect(find.byKey(const Key('pairingStatus')), findsOneWidget,
            reason: 'Status pairing harus tampil di Dashboard');

        print('[PASS] 1.4  Dashboard menampilkan status pairing');
      },
    );

    testWidgets(
      '1.5  Logout → kembali ke halaman Login',
      (tester) async {
        await tester.pumpWidget(const _StubApp());
        await tester.pumpAndSettle();

        // Login
        await tester.enterText(
            find.byKey(const Key('emailField')), _kValidEmail);
        await tester.enterText(
            find.byKey(const Key('passwordField')), _kValidPassword);
        await tester.tap(find.byKey(const Key('loginButton')));
        await tester.pumpAndSettle();

        expect(find.text('Dashboard'), findsOneWidget);

        // Logout
        await tester.tap(find.byKey(const Key('logoutButton')));
        await tester.pumpAndSettle();

        expect(find.text('WalkGuide — Login'), findsOneWidget,
            reason: 'Setelah logout harus kembali ke halaman Login');
        expect(find.byKey(const Key('emailField')), findsOneWidget,
            reason: 'Form login harus tampil kembali');

        print('[PASS] 1.5  Logout → kembali ke Login');
      },
    );

    testWidgets(
      '1.6  Full round-trip: Login → Dashboard → Logout → Login kembali',
      (tester) async {
        await tester.pumpWidget(const _StubApp());
        await tester.pumpAndSettle();

        // Login pertama
        await tester.enterText(
            find.byKey(const Key('emailField')), _kValidEmail);
        await tester.enterText(
            find.byKey(const Key('passwordField')), _kValidPassword);
        await tester.tap(find.byKey(const Key('loginButton')));
        await tester.pumpAndSettle();
        expect(find.text('Dashboard'), findsOneWidget);

        // Logout
        await tester.tap(find.byKey(const Key('logoutButton')));
        await tester.pumpAndSettle();
        expect(find.text('WalkGuide — Login'), findsOneWidget);

        // Login lagi
        await tester.enterText(
            find.byKey(const Key('emailField')), _kValidEmail);
        await tester.enterText(
            find.byKey(const Key('passwordField')), _kValidPassword);
        await tester.tap(find.byKey(const Key('loginButton')));
        await tester.pumpAndSettle();
        expect(find.text('Dashboard'), findsOneWidget,
            reason: 'User harus bisa login kembali setelah logout');

        print('[PASS] 1.6  Full round-trip Login → Logout → Login berhasil');
      },
    );
  });
}
