import 'package:flutter/material.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:logging/logging.dart';
import 'package:sheetless/api.dart';
import 'package:sheetless/home_page.dart';
import 'package:sheetless/storage_helper.dart';

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

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

class _LoginPageState extends State<LoginPage> {
  final log = Logger("_LoginPageState");

  final TextEditingController _urlController = TextEditingController(
    text: "https://sheetable.julian-mutter.de",
  );
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  final _formKey = GlobalKey<FormState>();

  final StorageHelper _storageHelper = StorageHelper();
  String? _error;
  bool loggingIn = false;

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

  Future<void> _restoreStoredValues() async {
    final jwt = await _storageHelper.readSecure(SecureStorageKey.jwt);
    if (jwt != null && await _isJwtValid(jwt)) {
      await _navigateToMainPage();
      return;
    }
    final url = await _storageHelper.readSecure(SecureStorageKey.url);
    final email = await _storageHelper.readSecure(SecureStorageKey.email);
    if (url != null) {
      _urlController.text = url;
    }
    if (email != null) {
      _emailController.text = email;
    }
  }

  Future<bool> _isJwtValid(String jwt) async {
    try {
      bool expired = JwtDecoder.isExpired(jwt);
      return !expired;
    } on FormatException {
      return false;
    }
  }

  Future<void> _login(String serverUrl, String email, String password) async {
    setState(() {
      _error = null;
    });
    final apiClient = ApiClient(baseUrl: "$serverUrl/api");
    final loginResult = await apiClient.login(email, password);
    if (loginResult.isOk()) {
      await _storageHelper.writeSecure(SecureStorageKey.url, serverUrl);
      await _storageHelper.writeSecure(SecureStorageKey.jwt, apiClient.token!);
      await _storageHelper.writeSecure(SecureStorageKey.email, email);
      await _navigateToMainPage();
    } else {
      setState(() {
        _error = "Login failed.\n${loginResult.error()}";
      });
    }
  }

  Future<void> _navigateToMainPage() async {
    final config = await _storageHelper.readConfig();
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(builder: (_) => MyHomePage(config: config)),
    );
  }

  String? validateNotEmpty(String? content) {
    if (content == null || content.isEmpty) {
      return "Do not leave this field empty";
    }
    return null;
  }

  void handleLoginPressed() async {
    if (loggingIn) return;

    loggingIn = true;
    if (_formKey.currentState!.validate()) {
      await _login(
        _urlController.text,
        _emailController.text,
        _passwordController.text,
      );
    }
    loggingIn = false;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextFormField(
                controller: _urlController,
                validator: validateNotEmpty,
                decoration: InputDecoration(labelText: 'Url'),
                textInputAction: TextInputAction.next,
              ),
              TextFormField(
                controller: _emailController,
                validator: validateNotEmpty,
                decoration: InputDecoration(labelText: 'Email'),
                textInputAction: TextInputAction.next,
              ),
              TextFormField(
                controller: _passwordController,
                validator: validateNotEmpty,
                // focusNode: _passwordFocusNode,
                decoration: InputDecoration(labelText: 'Password'),
                obscureText: true,
                textInputAction: TextInputAction
                    .next, // with submit or go, onFieldSubmitted is not called
                onFieldSubmitted: (_) => handleLoginPressed(),
              ),
              // ),
              SizedBox(height: 5),
              ElevatedButton(
                onPressed: loggingIn ? null : handleLoginPressed,
                child: Text('Login'),
              ),
              if (_error != null)
                Padding(
                  padding: const EdgeInsets.only(top: 8.0),
                  child: Text(_error!, style: TextStyle(color: Colors.red)),
                ),
            ],
          ),
        ),
      ),
    );
  }
}
