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

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

import '/components/custom_circle_avatar.dart';
import '/data_models/user_search.dart';
import '/models/my_profile.dart';
import '/utils/encryption/aes_helper.dart';
import '/utils/storage/session_cookie.dart';
import '/utils/strings.dart';
import '/utils/encryption/crypto_utils.dart';

@immutable
class UserSearchResult extends StatefulWidget {
  final UserSearch user;

  const UserSearchResult({
      Key? key,
      required this.user,
  }) : super(key: key);

  @override
  _UserSearchResultState createState() => _UserSearchResultState();
}

class _UserSearchResultState extends State<UserSearchResult>{
  bool showFailed = false;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.only(top: 30),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            CustomCircleAvatar(
              initials: widget.user.username[0].toUpperCase(),
              icon: const Icon(Icons.person, size: 80),
              radius: 50,
            ),
            const SizedBox(height: 10),
            Text(
              widget.user.username,
              style: const TextStyle(
                fontSize: 35,
              ),
            ),
            const SizedBox(height: 30),
            TextButton(
              onPressed: sendFriendRequest,
              child: Text(
                'Send Friend Request',
                style: TextStyle(
                  color: Theme.of(context).colorScheme.onPrimary,
                  fontSize: 20,
                ),
              ),
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.primary),
                padding: MaterialStateProperty.all<EdgeInsets>(
                  const EdgeInsets.only(left: 20, right: 20, top: 8, bottom: 8)),
              ),
            ),
            showFailed ? const SizedBox(height: 20) : const SizedBox.shrink(),
            failedMessage(context),
          ],
        ),
      ),
    );
  }

  Widget failedMessage(BuildContext context) {
    if (!showFailed) {
      return const SizedBox.shrink();
    }

    return Text(
      'Failed to send friend request',
      style: TextStyle(
        color: Theme.of(context).colorScheme.error,
        fontSize: 16,
      ),
    );
  }

  Future<void> sendFriendRequest() async {
    MyProfile profile = await MyProfile.getProfile();

    String publicKeyString = CryptoUtils.encodeRSAPublicKeyToPem(profile.publicKey!);

    RSAPublicKey friendPublicKey = CryptoUtils.rsaPublicKeyFromPem(widget.user.publicKey);

    final symmetricKey = AesHelper.deriveKey(generateRandomString(32));

    String payloadJson = jsonEncode({
      'user_id': widget.user.id,
      'friend_id': base64.encode(CryptoUtils.rsaEncrypt(
          Uint8List.fromList(profile.id.codeUnits),
          friendPublicKey,
      )),
      'friend_username': base64.encode(CryptoUtils.rsaEncrypt(
          Uint8List.fromList(profile.username.codeUnits),
          friendPublicKey,
      )),
      'symmetric_key': base64.encode(CryptoUtils.rsaEncrypt(
          Uint8List.fromList(symmetricKey),
          friendPublicKey,
      )),
      'asymmetric_public_key': AesHelper.aesEncrypt(
          symmetricKey,
          Uint8List.fromList(publicKeyString.codeUnits),
      ),
    });

    var resp = await http.post(
        await MyProfile.getServerUrl('api/v1/auth/friend_request'),
        headers: {
          'cookie': await getSessionCookie(),
        },
        body: payloadJson,
    );

    if (resp.statusCode != 200) {
      showFailed = true;
      setState(() {});
      return;
    }

    Navigator.pop(context);
  }
}
