// ignore_for_file: use_build_context_synchronously

import 'dart:async';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../../app/app_cubit.dart';
import '../../app/injection_container.dart';
import '../../core/constants/app_constants.dart';
import '../../core/network/api_client.dart';
import '../../core/services/offline_queue_service.dart';
import '../../core/services/tts_service.dart';
import '../../core/services/websocket_service.dart';
import '../../core/storage/secure_storage.dart';

// ---------------------------------------------------------------------------
// LoginScreen
// ---------------------------------------------------------------------------

class LoginScreen extends StatefulWidget {
  const LoginScreen({super.key});

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

class _LoginScreenState extends State<LoginScreen> {
  final _email = TextEditingController();
  final _password = TextEditingController();
  bool _loading = false;
  bool _showPassword = false;

  @override
  void initState() {
    super.initState();
    _loadPendingLoginEmail();
  }

  @override
  void dispose() {
    _email.dispose();
    _password.dispose();
    super.dispose();
  }

  Future<void> _loadPendingLoginEmail() async {
    final prefs = await SharedPreferences.getInstance();
    final pendingEmail = prefs.getString('pending_login_email');
    if (!mounted) return;
    setState(() {
      if (pendingEmail != null && pendingEmail.isNotEmpty) {
        _email.text = pendingEmail;
      }
    });
    await prefs.remove('pending_login_email');
  }

  Future<void> _login() async {
    if (_email.text.trim().isEmpty || _password.text.isEmpty) {
      _snack(context, 'Isi email dan password dulu.');
      return;
    }
    setState(() => _loading = true);
    try {
      final res = await sl<ApiClient>().dio.post('/auth/login', data: {
        'email': _email.text.trim(),
        'password': _password.text,
      });
      await _saveAuthAndRoute(
          context, Map<String, dynamic>.from(res.data['data'] as Map));
    } on DioException catch (e) {
      _snack(context, _friendlyDioMessage(e, fallback: 'Login gagal'));
    } catch (e) {
      _snack(context, 'Login gagal: $e');
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return _AuthFrame(
      title: 'Sign in',
      subtitle: 'Masuk sebagai Guardian atau User.',
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          TextField(
              controller: _email,
              keyboardType: TextInputType.emailAddress,
              textInputAction: TextInputAction.next,
              decoration: const InputDecoration(
                labelText: 'Email',
                prefixIcon: Icon(Icons.email_outlined),
              )),
          const SizedBox(height: 12),
          TextField(
              controller: _password,
              obscureText: !_showPassword,
              textInputAction: TextInputAction.done,
              onSubmitted: (_) => _login(),
              decoration: InputDecoration(
                labelText: 'Password',
                prefixIcon: const Icon(Icons.lock_outline),
                suffixIcon: IconButton(
                  icon: Icon(
                      _showPassword ? Icons.visibility_off : Icons.visibility),
                  onPressed: () =>
                      setState(() => _showPassword = !_showPassword),
                ),
              )),
          const SizedBox(height: 18),
          FilledButton.icon(
            onPressed: _loading ? null : _login,
            icon: _loading
                ? const SizedBox(
                    width: 18,
                    height: 18,
                    child: CircularProgressIndicator(strokeWidth: 2))
                : const Icon(Icons.login),
            label: const Text('Login'),
          ),
          TextButton(
              onPressed: () => context.go('/register'),
              child: const Text('Buat akun baru')),
        ],
      ),
    );
  }
}

// ---------------------------------------------------------------------------
// Shared private widgets
// ---------------------------------------------------------------------------

class _AuthFrame extends StatelessWidget {
  final String title;
  final String subtitle;
  final Widget child;
  const _AuthFrame(
      {required this.title, required this.subtitle, required this.child});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(24),
          child: ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: 460),
            child: Card(
              elevation: 0,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(18),
                  side: const BorderSide(color: Color(0xFFE2E8F0))),
              child: Padding(
                padding: const EdgeInsets.all(24),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    const Icon(Icons.navigation_rounded,
                        color: Color(0xFF1A56DB), size: 42),
                    const SizedBox(height: 14),
                    Text(title,
                        textAlign: TextAlign.center,
                        style: Theme.of(context)
                            .textTheme
                            .headlineSmall
                            ?.copyWith(fontWeight: FontWeight.w800)),
                    const SizedBox(height: 4),
                    Text(subtitle,
                        textAlign: TextAlign.center,
                        style: const TextStyle(color: Color(0xFF64748B))),
                    const SizedBox(height: 22),
                    child,
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

// ---------------------------------------------------------------------------
// Helpers (shared for login flow)
// ---------------------------------------------------------------------------

Future<void> _saveAuthAndRoute(
    BuildContext context, Map<String, dynamic> data) async {
  await sl<SecureStorage>().saveTokens(
    accessToken: data['accessToken'],
    refreshToken: data['refreshToken'],
    role: data['role'],
    userId: data['userId'].toString(),
    displayName: data['displayName'],
    uniqueUserId: data['uniqueUserId'],
  );
  final serverUrl = await AppConstants.getServerUrl();
  if (serverUrl != null) {
    context
        .read<AppCubit>()
        .setSession(role: data['role'], serverUrl: serverUrl);
    _startPostLoginServices(serverUrl);
  }
  sl<TtsService>().speak('Selamat datang ${data['displayName'] ?? ''}');
  if (context.mounted) {
    context.go(data['role'] == 'ROLE_GUARDIAN'
        ? '/guardian/dashboard'
        : '/user/walkguide');
  }
}

void _startPostLoginServices(String serverUrl) {
  Future.microtask(() async {
    try {
      await sl<WebSocketService>()
          .connect(serverUrl)
          .timeout(const Duration(seconds: 2));
      await sl<OfflineQueueService>()
          .syncPending(sl<ApiClient>())
          .timeout(const Duration(seconds: 3));
    } catch (e) {
      debugPrint('Post-login services skipped: $e');
    }
  });
}

void _snack(BuildContext context, String message) {
  if (context.mounted) {
    ScaffoldMessenger.of(context)
        .showSnackBar(SnackBar(content: Text(message)));
  }
}

String _friendlyDioMessage(DioException e, {required String fallback}) {
  final data = e.response?.data;
  if (data is Map && data['message'] != null) return data['message'].toString();
  if (e.response?.statusCode == 401) {
    return 'Email atau password salah.';
  }
  if (e.type == DioExceptionType.connectionTimeout ||
      e.type == DioExceptionType.receiveTimeout) {
    return 'Server terlalu lama merespons. Pastikan backend masih running dan URL server benar.';
  }
  if (e.type == DioExceptionType.connectionError) {
    return 'Tidak bisa ke server. Di Chrome pakai http://localhost:8080. Di HP pakai IP laptop/server, bukan localhost.';
  }
  return fallback;
}
