import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import '/components/flash_message.dart';
import '/models/my_profile.dart';
import '/utils/storage/session_cookie.dart';

class LoginResponse {
  final String userId;
  final String username;
  final String publicKey;
  final String privateKey;
  final String symmetricKey;
  final String? imageLink;

  const LoginResponse({
    required this.publicKey,
    required this.privateKey,
    required this.symmetricKey,
    required this.userId,
    required this.username,
    this.imageLink,
  });

  factory LoginResponse.fromJson(Map<String, dynamic> json) {
    return LoginResponse(
      userId: json['user_id'],
      username: json['username'],
      publicKey: json['asymmetric_public_key'],
      privateKey: json['asymmetric_private_key'],
      symmetricKey: json['symmetric_key'],
      imageLink: json['image_link'],
    );
  }
}

class Login extends StatelessWidget {
  const Login({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: null,
        automaticallyImplyLeading: true,
        leading: IconButton(icon: const Icon(Icons.arrow_back),
          onPressed:() => {
            Navigator.pop(context)
          }
        ),
        backgroundColor: Colors.transparent,
        shadowColor: Colors.transparent,
      ),
      body: const SafeArea(
        child: LoginWidget(),
      ),
    );
  }
}

class LoginWidget extends StatefulWidget {
  const LoginWidget({Key? key}) : super(key: key);

  @override
  State<LoginWidget> createState() => _LoginWidgetState();
}

class _LoginWidgetState extends State<LoginWidget> {
  final _formKey = GlobalKey<FormState>();

  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    const TextStyle inputTextStyle = TextStyle(
      fontSize: 18,
    );

    final OutlineInputBorder inputBorderStyle = OutlineInputBorder(
      borderRadius: BorderRadius.circular(5),
      borderSide: const BorderSide(
        color: Colors.transparent,
      )
    );

    final ButtonStyle buttonStyle = ElevatedButton.styleFrom(
      backgroundColor: Theme.of(context).colorScheme.surface,
      foregroundColor: Theme.of(context).colorScheme.onSurface,
      minimumSize: const Size.fromHeight(50),
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
      textStyle: TextStyle(
        fontSize: 20,
        fontWeight: FontWeight.bold,
        color: Theme.of(context).colorScheme.error,
      ),
    );

    return Center(
      child: Form(
        key: _formKey,
        child: Center(
          child: Padding(
            padding: const EdgeInsets.only(
              left: 20,
              right: 20,
              top: 0,
              bottom: 80,
            ),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(
                  'Login',
                  style: TextStyle(
                    fontSize: 35,
                    color: Theme.of(context).colorScheme.onBackground,
                  ),
                ),
                const SizedBox(height: 30),
                TextFormField(
                  controller: _usernameController,
                  decoration: InputDecoration(
                    hintText: 'Username',
                    enabledBorder: inputBorderStyle,
                    focusedBorder: inputBorderStyle,
                  ),
                  style: inputTextStyle,
                  // The validator receives the text that the user has entered.
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Enter a username';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 10),
                TextFormField(
                  controller: _passwordController,
                  obscureText: true,
                  enableSuggestions: false,
                  autocorrect: false,
                  decoration: InputDecoration(
                    hintText: 'Password',
                    enabledBorder: inputBorderStyle,
                    focusedBorder: inputBorderStyle,
                  ),
                  style: inputTextStyle,
                  // The validator receives the text that the user has entered.
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Enter a password';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 15),
                ElevatedButton(
                  style: buttonStyle,
                  onPressed: () {
                    if (_formKey.currentState!.validate()) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(content: Text('Processing Data')),
                      );

                      login()
                        .then((val) {
                          Navigator.
                            pushNamedAndRemoveUntil(
                              context,
                              '/home',
                              ModalRoute.withName('/home'),
                            );
                        }).catchError((error) {
                          print(error);
                          showMessage(
                            'Could not login to Capsule, please try again later.',
                            context,
                          );
                        });
                    }
                  },
                  child: const Text('Submit'),
                ),
              ],
            )
          )
        )
      )
    );
  }

  Future<dynamic> login() async {
    final resp = await http.post(
      await MyProfile.getServerUrl('api/v1/login'),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
      body: jsonEncode(<String, String>{
        'username': _usernameController.text,
        'password': _passwordController.text,
      }),
    );

    if (resp.statusCode != 200) {
      throw Exception(resp.body);
    }

    String? rawCookie = resp.headers['set-cookie'];
    if (rawCookie != null) {
      int index = rawCookie.indexOf(';');
      setSessionCookie((index == -1) ? rawCookie : rawCookie.substring(0, index));
    }

    return await MyProfile.login(
      json.decode(resp.body),
      _passwordController.text,
    );
  }
}
