import 'package:flutter/material.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:logging/logging.dart';
import 'package:sheetless/core/services/api_client.dart';
import 'package:sheetless/core/services/storage_service.dart';

import '../home/home_page.dart';

/// Login page for authenticating with the Sheetless server.
class LoginPage extends StatefulWidget {
  const LoginPage({super.key});

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final _log = Logger('LoginPage');
  final _formKey = GlobalKey<FormState>();
  final _storageService = StorageService();

  final _urlController = TextEditingController(
    text: 'https://sheetless.julian-mutter.de',
  );
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

  String? _errorMessage;
  bool _isLoggingIn = false;

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

  @override
  void dispose() {
    _urlController.dispose();
    _usernameController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  // ---------------------------------------------------------------------------
  // Auto-Login
  // ---------------------------------------------------------------------------

  /// Attempts to auto-login using a stored JWT token.
  Future<void> _tryAutoLogin() async {
    final refreshToken = await _storageService.readSecure(
      SecureStorageKey.refreshToken,
    );

    if (refreshToken != null) {
      // TODO: this assumes the refresh token is always valid
      await _navigateToHome();
      return;
    }

    // Restore saved credentials for convenience
    await _restoreCredentials();
  }

  /// Checks if a JWT token is still valid (not expired).
  bool _isTokenValid(String jwt) {
    try {
      return !JwtDecoder.isExpired(jwt);
    } on FormatException {
      return false;
    }
  }

  /// Restores previously saved URL and username for convenience.
  Future<void> _restoreCredentials() async {
    final url = await _storageService.readSecure(SecureStorageKey.url);
    final username = await _storageService.readSecure(
      SecureStorageKey.username,
    );

    if (url != null) _urlController.text = url;
    if (username != null) _usernameController.text = username;
  }

  // ---------------------------------------------------------------------------
  // Login
  // ---------------------------------------------------------------------------

  /// Handles the login button press.
  Future<void> _handleLogin() async {
    if (_isLoggingIn) return;
    if (!_formKey.currentState!.validate()) return;

    setState(() {
      _isLoggingIn = true;
      _errorMessage = null;
    });

    try {
      final apiClient = ApiClient(baseUrl: _urlController.text);
      await apiClient.login(_usernameController.text, _passwordController.text);

      // Save credentials for next time
      if (apiClient.refreshToken == null) {
        _log.warning('Login failed, refreshToken is null');
        setState(() {
          _errorMessage = 'Login failed.\nRefresh token is null';
        });
      } else {
        await _saveCredentials(apiClient.refreshToken!);
        await _navigateToHome();
      }
    } catch (e) {
      _log.warning('Login failed', e);
      setState(() {
        _errorMessage = 'Login failed.\n$e';
      });
    } finally {
      if (mounted) {
        setState(() => _isLoggingIn = false);
      }
    }
  }

  /// Saves credentials after successful login.
  Future<void> _saveCredentials(String refreshToken) async {
    await _storageService.writeSecure(
      SecureStorageKey.url,
      _urlController.text,
    );
    await _storageService.writeSecure(
      SecureStorageKey.refreshToken,
      refreshToken,
    );
    await _storageService.writeSecure(
      SecureStorageKey.username,
      _usernameController.text,
    );
  }

  /// Navigates to the home page after successful authentication.
  Future<void> _navigateToHome() async {
    final config = await _storageService.readConfig();

    if (!mounted) return;
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(builder: (_) => HomePage(config: config)),
    );
  }

  // ---------------------------------------------------------------------------
  // Validation
  // ---------------------------------------------------------------------------

  String? _validateNotEmpty(String? value) {
    if (value == null || value.isEmpty) {
      return 'This field is required';
    }
    return null;
  }

  // ---------------------------------------------------------------------------
  // UI
  // ---------------------------------------------------------------------------

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Login')),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                _buildUrlField(),
                const SizedBox(height: 16),
                _buildUsernameField(),
                const SizedBox(height: 16),
                _buildPasswordField(),
                const SizedBox(height: 24),
                _buildLoginButton(),
                if (_errorMessage != null) _buildErrorMessage(),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildUrlField() {
    return TextFormField(
      controller: _urlController,
      validator: _validateNotEmpty,
      decoration: const InputDecoration(
        labelText: 'Server URL',
        prefixIcon: Icon(Icons.dns),
      ),
      keyboardType: TextInputType.url,
      textInputAction: TextInputAction.next,
    );
  }

  Widget _buildUsernameField() {
    return TextFormField(
      controller: _usernameController,
      validator: _validateNotEmpty,
      decoration: const InputDecoration(
        labelText: 'Username',
        prefixIcon: Icon(Icons.person),
      ),
      textInputAction: TextInputAction.next,
    );
  }

  Widget _buildPasswordField() {
    return TextFormField(
      controller: _passwordController,
      validator: _validateNotEmpty,
      decoration: const InputDecoration(
        labelText: 'Password',
        prefixIcon: Icon(Icons.lock),
      ),
      obscureText: true,
      textInputAction: TextInputAction.done,
      onFieldSubmitted: (_) => _handleLogin(),
    );
  }

  Widget _buildLoginButton() {
    return ElevatedButton(
      onPressed: _isLoggingIn ? null : _handleLogin,
      child: _isLoggingIn
          ? const SizedBox(
              height: 20,
              width: 20,
              child: CircularProgressIndicator(strokeWidth: 2),
            )
          : const Text('Login'),
    );
  }

  Widget _buildErrorMessage() {
    return Padding(
      padding: const EdgeInsets.only(top: 16.0),
      child: Text(
        _errorMessage!,
        style: const TextStyle(color: Colors.red),
        textAlign: TextAlign.center,
      ),
    );
  }
}
