import 'package:dart_nostr/dart_nostr.dart';
import 'package:drifter/models/keys.dart';
import 'package:drifter/pages/profile_screen/widgets/delete_keys_dialog.dart';
import 'package:drifter/main.dart';
import 'package:drifter/pages/profile_screen/widgets/key_exist_dialog.dart';
import 'package:drifter/pages/profile_screen/widgets/keys_option_modal_bottom_sheet.dart';
import 'package:drifter/pages/profile_screen/widgets/message_snack_bar.dart';
import 'package:drifter/pages/profile_screen/widgets/user_info_widget.dart';
import 'package:drifter/theme/app_colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

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

  @override
  State<ProfileScreen> createState() => ProfileScreenState();
}

class ProfileScreenState extends State<ProfileScreen> {
  final secureStorage = const FlutterSecureStorage();
  bool _toHex = false;

  TextEditingController privateKeyInput = TextEditingController();
  TextEditingController publicKeyInput = TextEditingController();

  // final keyGenerator = KeyApi();
  // final nip19 = Nip19();

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

  Future<bool> generateNewKeys() async {
    final newPrivateKey = await Nostr.instance.keysService.generatePrivateKey();
    // final newPrivateKey = keyGenerator.generatePrivateKey();

    final nsec =
        Nostr.instance.keysService.encodePrivateKeyToNsec(newPrivateKey);

    // final nsecDecoded =
    //     Nostr.instance.keysService.decodeNsecKeyToPrivateKey(nsec);
    // assert(nsecDecoded['type'] == 'nsec');
    // assert(nsecDecoded['data'] == newPrivateKey);

    final newPublicKey = await Nostr.instance.keysService
        .derivePublicKey(privateKey: newPrivateKey);
    // final newPublicKey = keyGenerator.getPublicKey(newPrivateKey);

    final npub = Nostr.instance.keysService.encodePublicKeyToNpub(newPublicKey);

    // final npubDecoded =
    //     Nostr.instance.keysService.decodeNpubKeyToPublicKey(npub);
    // assert(npubDecoded['type'] == 'npub');
    // assert(npubDecoded['data'] == newPublicKey);

    return await addKeyToStorage(newPrivateKey, newPublicKey, nsec, npub);
  }

  Future<void> _getKeysFromStorage() async {
    // Reading values associated with the " privateKey " and " publicKey " keys from a secure repository
    final storedPrivateKey = await secureStorage.read(key: 'privateKey');
    final storedPublicKey = await secureStorage.read(key: 'publicKey');

    final storedNsecKey = await secureStorage.read(key: 'nsec');
    final storedNpubKey = await secureStorage.read(key: 'npub');

    // Indicates that both private and public keys are stored in a secure repository, after which, the state variables are updated
    if (storedPrivateKey != null &&
        storedPublicKey != null &&
        storedNsecKey != null &&
        storedNpubKey != null) {
      setState(() {
        Keys.privateKey = storedPrivateKey;
        Keys.publicKey = storedPublicKey;
        Keys.nsecKey = storedNsecKey;
        Keys.npubKey = storedNpubKey;
        Keys.keysExist = true;
      });
    }
  }

  // Adding a new key
// Writing a private and public key to a secure vault
  Future<bool> addKeyToStorage(
    String privateKeyHex,
    String publicKeyHex,
    String nsecKey,
    String npubKey,
  ) async {
// Waiting for both write operations to complete
    Future.wait([
      secureStorage.write(key: 'privateKey', value: privateKeyHex),
      secureStorage.write(key: 'publicKey', value: publicKeyHex),
      secureStorage.write(key: 'nsec', value: nsecKey),
      secureStorage.write(key: 'npub', value: npubKey),
    ]);

    // Updating status variables and starting widget rebuilding
    setState(() {
      Keys.privateKey = privateKeyHex;
      Keys.publicKey = publicKeyHex;
      Keys.nsecKey = nsecKey;
      Keys.npubKey = npubKey;
      Keys.keysExist = true;
    });

// Returns a boolean value indicating whether the keys were successfully added to the repository or not.
    return Keys.keysExist;
  }

  Future<void> _deleteKeysStorage() async {
    // Calling secure storage to remove keys from storage
    Future.wait([
      secureStorage.delete(key: 'privateKey'),
      secureStorage.delete(key: 'publicKey'),
      secureStorage.delete(key: 'nsec'),
      secureStorage.delete(key: 'npub'),
    ]);

    // Updating status variables, resetting values after deleting keys from the repository
    setState(() {
      Keys.privateKey = '';
      Keys.publicKey = '';
      Keys.nsecKey = '';
      Keys.npubKey = '';
      Keys.keysExist = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    privateKeyInput.text = _toHex ? Keys.nsecKey : Keys.privateKey;
    publicKeyInput.text = _toHex ? Keys.npubKey : Keys.publicKey;

    return ListView(
      children: [
        const SizedBox(
          height: 60,
        ),
        const UserInfo(),
        const SizedBox(
          height: 40,
        ),
        FormKeys(),
        const SizedBox(height: 20),
        Padding(
          padding: const EdgeInsets.all(16.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Keys.keysExist
                  ? IconButton(
                      onPressed: () {
                        setState(() {
                          _toHex = !_toHex;
                        });
                      },
                      icon: const Icon(Icons.refresh))
                  // ElevatedButton(
                  //     style: ButtonStyle(
                  //         backgroundColor:
                  //             MaterialStateProperty.all(AppColors.background)),
                  //     onPressed: () {
                  //       keysExistDialog(
                  //         Nostr.instance.keysService
                  //             .encodePublicKeyToNpub(Keys.publicKey),
                  //         Nostr.instance.keysService
                  //             .encodePrivateKeyToNsec(Keys.privateKey),
                  //       );
                  //     },
                  //     child: const Text(
                  //       'Keys',
                  //     ),
                  //   )
                  : Row(
                      children: [
                        ElevatedButton(
                          style: ButtonStyle(
                              backgroundColor: MaterialStateProperty.all(
                                  AppColors.background)),
                          onPressed: () {
                            modalBottomSheet();
                          },
                          child: const Text(
                            'Generate Keys',
                          ),
                        ),
                        SizedBox(width: 100),
                        ElevatedButton(
                          style: ButtonStyle(
                              backgroundColor: MaterialStateProperty.all(
                                  AppColors.background)),
                          onPressed: () {
                            Navigator.pushNamed(context, '/login').then((_) {
                              initState();
                            });
                          },
                          child: const Text(
                            'Login',
                          ),
                        ),
                      ],
                    ),
              Keys.keysExist
                  ? Row(
                      children: [
                        IconButton(
                            onPressed: () {
                              deleteKeysDialog();
                            },
                            icon: const Icon(Icons.delete)),
                      ],
                    )
                  : Container(),
            ],
          ),
        )
      ],
    );
  }

  Form FormKeys() {
    return Form(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextFormField(
              controller: privateKeyInput,
              // _toHex ? widget.hexPriv : widget.nsecEncoded,

              decoration: const InputDecoration(
                labelText: 'Private Key',
                border: OutlineInputBorder(),
              ),
              maxLength: 64,
            ),
            const SizedBox(
              height: 20,
            ),
            TextFormField(
              controller: publicKeyInput,
              //  _toHex ? widget.hexPub : widget.npubEncoded,
              decoration: const InputDecoration(
                labelText: 'Public Key',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(
              height: 40,
            ),
            TextFormField(
              decoration: const InputDecoration(
                labelText: 'Relay',
                border: OutlineInputBorder(),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void modalBottomSheet() {
    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return KeysOptionModalBottomSheet(
            generateNewKeyPressed: () {
              final currentContext = context;
              generateNewKeys().then(
                (keysGenerated) {
                  if (keysGenerated) {
                    ScaffoldMessenger.of(currentContext).showSnackBar(
                        MessageSnackBar(label: 'Keys Generated!'));
                  }
                },
              );
              Navigator.pop(context);
            },
          );
        });
  }

  void keysExistDialog(String npubEncode, String nsecEncode) async {
    await showDialog(
      context: context,
      builder: ((context) {
        return KeysExistDialog(
          npubEncoded: npubEncode,
          nsecEncoded: nsecEncode,
          hexPriv: Keys.privateKey,
          hexPub: Keys.publicKey,
        );
      }),
    );
  }

  void deleteKeysDialog() async {
    await showDialog(
      context: context,
      builder: ((context) {
        return DeleteKeysDialog(
          onNoPressed: () {
            Navigator.pop(context);
          },
          onYesPressed: () {
            final currentContext = context;
            _deleteKeysStorage().then((_) {
              if (!Keys.keysExist) {
                ScaffoldMessenger.of(currentContext).showSnackBar(
                  MessageSnackBar(
                    label: 'Keys successfully deleted!',
                    isWarning: true,
                  ),
                );
              }
            });
            Navigator.pop(context);
          },
        );
      }),
    );
  }
}
