import 'dart:convert';
import 'dart:typed_data';

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

import '/components/flash_message.dart';
import '/components/custom_title_bar.dart';
import '/models/my_profile.dart';
import '/utils/encryption/aes_helper.dart';
import '/utils/encryption/crypto_utils.dart';
import '/utils/storage/session_cookie.dart';

@immutable
class ChangePassword extends StatelessWidget {
  ChangePassword({
    Key? key,
    required this.privateKey
  }) : super(key: key);

  final RSAPrivateKey privateKey;

  final _formKey = GlobalKey<FormState>();

  final TextEditingController _currentPasswordController = TextEditingController();
  final TextEditingController _newPasswordController = TextEditingController();
  final TextEditingController _newPasswordConfirmController = TextEditingController();

  bool invalidCurrentPassword = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: const CustomTitleBar(
        title: Text(
          'Profile',
          style: TextStyle(
            fontSize: 32,
            fontWeight: FontWeight.bold
          )
        ),
        showBack: true,
        backgroundColor: Colors.transparent,
      ),
      body: Form(
        key: _formKey,
        child: Padding(
          padding: const EdgeInsets.only(
            left: 20,
            right: 20,
            top: 30,
          ),
          child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const Text(
                  'Change Password',
                  style: TextStyle(
                    fontSize: 25,
                  ),
                ),
                const SizedBox(height: 30),
                TextFormField(
                  controller: _currentPasswordController,
                  decoration: const InputDecoration(
                      hintText: 'Current Password',
                  ),
                  // The validator receives the text that the user has entered.
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Enter your current password';
                    }
                    if (invalidCurrentPassword) {
                      return 'Invalid password';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 10),
                TextFormField(
                  controller: _newPasswordController,
                  obscureText: true,
                  enableSuggestions: false,
                  autocorrect: false,
                  decoration: const InputDecoration(
                      hintText: 'New Password',
                  ),
                  // The validator receives the text that the user has entered.
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Enter a new password';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 10),
                TextFormField(
                  controller: _newPasswordConfirmController,
                  obscureText: true,
                  enableSuggestions: false,
                  autocorrect: false,
                  decoration: const InputDecoration(
                      hintText: 'Confirm Password',
                  ),
                  // The validator receives the text that the user has entered.
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Confirm your password';
                    }
                    if (value != _newPasswordController.text) {
                      return 'Passwords do not match';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 15),
                ElevatedButton(
                  onPressed: () {
                    if (!_formKey.currentState!.validate()) {
                      return;
                    }

                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(content: Text('Processing Data')),
                    );

                    _changePassword(context)
                      .then((dynamic) {
                        Navigator.of(context).pop();
                      });
                  },
                  child: const Text('Submit'),
              ),
            ],
          )
        )
      )
    );
  }

  Future<void> _changePassword(BuildContext context) async {
    String privateKeyPem = CryptoUtils.encodeRSAPrivateKeyToPem(privateKey);

    String privateKeyEncrypted = AesHelper.aesEncrypt(
      _newPasswordController.text,
      Uint8List.fromList(privateKeyPem.codeUnits),
    );

    String payload = jsonEncode({
      'old_password': _currentPasswordController.text,
      'new_password': _newPasswordController.text,
      'new_password_confirm': _newPasswordConfirmController.text,
      'private_key': privateKeyEncrypted,
    });

    var resp = await http.post(
      await MyProfile.getServerUrl('api/v1/auth/change_password'),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
        'cookie': await getSessionCookie(),
      },
      body: payload,
    );

    if (resp.statusCode == 403) {
      invalidCurrentPassword = true;
      _formKey.currentState!.validate();
      return;
    }

    if (resp.statusCode != 204) {
      showMessage(
        'An unexpected error occured, please try again later.',
        context,
      );
    }
  }
}

