part of '../../app/app.dart';

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

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

class _LoginScreenState extends State<LoginScreen> {
  final _formKey = GlobalKey<FormState>();
  final _baseUrl = TextEditingController(text: kDefaultBaseUrl);
  final _username = TextEditingController();
  final _password = TextEditingController();
  bool _obscure = true;
  bool _loading = false;
  bool _pinging = false;
  String? _pingStatus;

  @override
  void initState() {
    super.initState();
    SessionStore.session().then((value) {
      if (!mounted) {
        return;
      }
      _baseUrl.text = value.baseUrl;
      _username.text = value.username ?? '';
      _password.text = value.password ?? '';
    });
  }

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

  Future<void> _login() async {
    if (!_formKey.currentState!.validate()) {
      return;
    }
    setState(() => _loading = true);
    try {
      final serverUrl = normalizeBaseUrl(_baseUrl.text);
      final api = ApiClient(baseUrl: serverUrl);
      final data = await api.post('api/mobile/login', {
        'username': _username.text.trim(),
        'password': _password.text,
      });
      final token = data['token']?.toString();
      if (token == null || token.isEmpty) {
        throw ApiException('Token login tidak diterima dari server.');
      }
      await SessionStore.saveLogin(
        baseUrl: serverUrl,
        token: token,
        username: _username.text.trim(),
        password: _password.text,
      );
      if (!mounted) {
        return;
      }
      Navigator.of(context).pushReplacement(
        MaterialPageRoute(
          builder: (_) => DashboardScreen(token: token, baseUrl: serverUrl),
        ),
      );
    } on ApiException catch (error) {
      _showMessage(error.message);
    } catch (error, stackTrace) {
      debugPrint('Login MyLIS gagal tidak terduga: $error');
      debugPrintStack(stackTrace: stackTrace);
      _showMessage('Tidak bisa terhubung ke server MyLIS. Penyebab: $error');
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  Future<void> _ping() async {
    final serverUrl = normalizeBaseUrl(_baseUrl.text);
    if (serverUrl.isEmpty) {
      return;
    }
    setState(() {
      _pinging = true;
      _pingStatus = null;
    });

    try {
      await SessionStore.saveBaseUrl(serverUrl);
      final data = await ApiClient(baseUrl: serverUrl).get('api/mobile/ping');
      final appName = data['application']?.toString();
      setState(() {
        _baseUrl.text = serverUrl;
        _pingStatus = appName == null || appName.isEmpty
            ? 'Server bisa diakses.'
            : 'Server bisa diakses: $appName';
      });
    } on ApiException catch (error) {
      setState(() => _pingStatus = error.message);
    } catch (error, stackTrace) {
      debugPrint('Ping MyLIS gagal tidak terduga: $error');
      debugPrintStack(stackTrace: stackTrace);
      setState(() => _pingStatus = 'Koneksi server gagal. Penyebab: $error');
    } finally {
      if (mounted) setState(() => _pinging = false);
    }
  }

  void _showMessage(String message) {
    ScaffoldMessenger.of(
      context,
    ).showSnackBar(SnackBar(content: Text(message)));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(24),
            child: ConstrainedBox(
              constraints: const BoxConstraints(maxWidth: 420),
              child: Form(
                key: _formKey,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Flexible(
                          child: Image.asset(
                            kAppLogoAsset,
                            height: 78,
                            fit: BoxFit.contain,
                          ),
                        ),
                        const SizedBox(width: 18),
                        Container(
                          width: 1,
                          height: 58,
                          color: const Color(0xFFE2E8F0),
                        ),
                        const SizedBox(width: 18),
                        Flexible(
                          child: Image.asset(
                            kHospitalLogoAsset,
                            height: 78,
                            fit: BoxFit.contain,
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 18),
                    Text(
                      kHospitalName,
                      textAlign: TextAlign.center,
                      style: Theme.of(context).textTheme.titleSmall?.copyWith(
                        fontWeight: FontWeight.w700,
                        color: const Color(0xFF0F766E),
                      ),
                    ),
                    const SizedBox(height: 8),
                    Text(
                      kAppLongName,
                      textAlign: TextAlign.center,
                      style: Theme.of(context).textTheme.headlineMedium
                          ?.copyWith(fontWeight: FontWeight.w700),
                    ),
                    const SizedBox(height: 8),
                    Text(
                      'Login petugas',
                      textAlign: TextAlign.center,
                      style: Theme.of(
                        context,
                      ).textTheme.bodyLarge?.copyWith(color: Colors.black54),
                    ),
                    const SizedBox(height: 32),
                    TextFormField(
                      controller: _baseUrl,
                      keyboardType: TextInputType.url,
                      textInputAction: TextInputAction.next,
                      decoration: InputDecoration(
                        prefixIcon: const Icon(Icons.link),
                        labelText: 'IP Server',
                        border: const OutlineInputBorder(),
                        suffixIcon: IconButton(
                          tooltip: 'Ping server',
                          onPressed: _pinging ? null : _ping,
                          icon: _pinging
                              ? const SizedBox.square(
                                  dimension: 18,
                                  child: CircularProgressIndicator(
                                    strokeWidth: 2,
                                  ),
                                )
                              : const Icon(Icons.network_ping),
                        ),
                      ),
                      validator: (value) {
                        final url = normalizeBaseUrl(value ?? '');
                        final uri = Uri.tryParse(url);
                        return uri == null ||
                                !uri.hasScheme ||
                                !uri.hasAuthority
                            ? 'URL Laravel tidak valid'
                            : null;
                      },
                    ),
                    if (_pingStatus != null) ...[
                      const SizedBox(height: 8),
                      Text(
                        _pingStatus!,
                        textAlign: TextAlign.center,
                        style: Theme.of(context).textTheme.bodySmall?.copyWith(
                          color: _pingStatus!.contains('bisa diakses')
                              ? const Color(0xFF15803D)
                              : const Color(0xFFDC2626),
                        ),
                      ),
                    ],
                    const SizedBox(height: 14),
                    TextFormField(
                      controller: _username,
                      textInputAction: TextInputAction.next,
                      decoration: const InputDecoration(
                        prefixIcon: Icon(Icons.person_outline),
                        labelText: 'Username',
                        border: OutlineInputBorder(),
                      ),
                      validator: (value) =>
                          value == null || value.trim().isEmpty
                          ? 'Username wajib diisi'
                          : null,
                    ),
                    const SizedBox(height: 14),
                    TextFormField(
                      controller: _password,
                      obscureText: _obscure,
                      onFieldSubmitted: (_) => _login(),
                      decoration: InputDecoration(
                        prefixIcon: const Icon(Icons.lock_outline),
                        labelText: 'Password',
                        border: const OutlineInputBorder(),
                        suffixIcon: IconButton(
                          tooltip: _obscure
                              ? 'Tampilkan password'
                              : 'Sembunyikan password',
                          onPressed: () => setState(() => _obscure = !_obscure),
                          icon: Icon(
                            _obscure
                                ? Icons.visibility_outlined
                                : Icons.visibility_off_outlined,
                          ),
                        ),
                      ),
                      validator: (value) => value == null || value.isEmpty
                          ? 'Password wajib diisi'
                          : null,
                    ),
                    const SizedBox(height: 22),
                    FilledButton.icon(
                      onPressed: _loading ? null : _login,
                      icon: _loading
                          ? const SizedBox.square(
                              dimension: 18,
                              child: CircularProgressIndicator(strokeWidth: 2),
                            )
                          : const Icon(Icons.login),
                      label: const Text('Login'),
                    ),
                    const SizedBox(height: 18),
                    Text(
                      'Duidev Software House | CV Swandhana',
                      textAlign: TextAlign.center,
                      style: Theme.of(
                        context,
                      ).textTheme.bodySmall?.copyWith(color: Colors.black45),
                    ),
                    const SizedBox(height: 18),
                    Text(
                      'Copyright @ 2026',
                      textAlign: TextAlign.center,
                      style: Theme.of(context).textTheme.bodySmall?.copyWith(
                        color: Colors.black54,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
