import 'dart:async';

import 'package:drift/drift.dart' hide Column;
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/constants/routes.keys.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/tables/contacts.table.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/services/signal/session.signal.dart';
import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/components/alert.dialog.dart';
import 'package:twonly/src/visual/components/avatar_icon.comp.dart';
import 'package:twonly/src/visual/components/contact_labels.comp.dart';
import 'package:twonly/src/visual/components/flame_counter.comp.dart';
import 'package:twonly/src/visual/components/select_chat_deletion_time.comp.dart';
import 'package:twonly/src/visual/components/snackbar.dart';
import 'package:twonly/src/visual/components/verification_badge.comp.dart';
import 'package:twonly/src/visual/elements/better_list_title.element.dart';
import 'package:twonly/src/visual/views/contact/contact_components/mutual_groups_expansion_tile.comp.dart';
import 'package:twonly/src/visual/views/contact/contact_components/restore_flame.comp.dart';
import 'package:twonly/src/visual/views/contact/contact_components/user_discovery_contact_settings.comp.dart';
import 'package:twonly/src/visual/views/contact/contact_components/verification_expansion_tile.comp.dart';
import 'package:twonly/src/visual/views/contact/select_contact_labels.view.dart';
import 'package:twonly/src/visual/views/groups/group.view.dart';

class ContactView extends StatefulWidget {
  const ContactView(this.userId, {super.key});

  final int userId;

  @override
  State<ContactView> createState() => _ContactViewState();
}

class _ContactViewState extends State<ContactView> {
  Contact? _contact;
  List<GroupMember> _memberOfGroups = [];

  late StreamSubscription<Contact?> _streamContact;
  late StreamSubscription<List<GroupMember>> _streamMemberOfGroups;

  @override
  void initState() {
    super.initState();
    _streamContact = twonlyDB.contactsDao.watchContact(widget.userId).listen((
      update,
    ) {
      if (update != null) {
        setState(() {
          _contact = update;
        });
      }
    });
    _streamMemberOfGroups = twonlyDB.groupsDao
        .watchContactGroupMember(widget.userId)
        .listen((groups) async {
          if (!mounted) return;
          setState(() {
            _memberOfGroups = groups;
          });
        });
  }

  @override
  void dispose() {
    _streamContact.cancel();
    _streamMemberOfGroups.cancel();
    super.dispose();
  }

  Future<void> handleUserRemoveRequest(Contact contact) async {
    var delete = true;
    for (final groupM in _memberOfGroups) {
      final group = await twonlyDB.groupsDao.getGroup(groupM.groupId);
      if (group?.deletedContent ?? false) {
        await twonlyDB.groupsDao.deleteGroup(group!.groupId);
      } else {
        delete = false;
      }
    }
    if (!mounted) return;

    if (!delete) {
      showSnackbar(context, context.lang.deleteUserErrorMessage);
      return;
    }

    final remove = await showAlertDialog(
      context,
      context.lang.contactRemoveTitle(
        getContactDisplayName(contact, maxLength: 20),
      ),
      context.lang.contactRemoveBody,
    );
    if (remove) {
      await twonlyDB.contactsDao.deleteContactByUserId(contact.userId);
      if (mounted) {
        Navigator.popUntil(context, (route) => route.isFirst);
      }
    }
  }

  Future<void> handleUserBlockRequest(Contact contact) async {
    final block = await showAlertDialog(
      context,
      context.lang.contactBlockTitle(getContactDisplayName(contact)),
      context.lang.contactBlockBody,
    );
    if (block) {
      const update = ContactsCompanion(blocked: Value(true));
      if (context.mounted) {
        await twonlyDB.contactsDao.updateContact(contact.userId, update);
      }
      if (mounted) {
        Navigator.popUntil(context, (route) => route.isFirst);
      }
    }
  }

  Future<void> handleReportUser(Contact contact) async {
    final reason = await showReportDialog(context, contact);
    if (reason == null) return;
    final res = await apiService.reportUser(contact.userId, reason);
    if (!mounted) return;
    if (res.isSuccess) {
      showSnackbar(
        context,
        context.lang.userGotReported,
        level: SnackbarLevel.info,
      );
    } else {
      showNetworkIssue(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_contact == null) return Container();
    final contact = _contact!;

    return Scaffold(
      appBar: AppBar(
        title: const Text(''),
      ),
      body: ListView(
        key: ValueKey(contact.userId),
        children: [
          Center(
            child: GestureDetector(
              onTap: () {
                // ignore: inference_failure_on_function_invocation
                showDialog(
                  context: context,
                  builder: (context) {
                    return Dialog(
                      backgroundColor: Colors.transparent,
                      elevation: 0,
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          AvatarIcon(contactId: contact.userId, fontSize: 200),
                        ],
                      ),
                    );
                  },
                );
              },
              child: Padding(
                padding: const EdgeInsets.all(10),
                child: AvatarIcon(contactId: contact.userId, fontSize: 30),
              ),
            ),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                getContactDisplayName(contact, maxLength: 20),
                style: const TextStyle(fontSize: 20),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 1, right: 8),
                child: VerificationBadgeComp(
                  contact: contact,
                ),
              ),
              FlameCounterWidget(
                contactId: contact.userId,
              ),
            ],
          ),
          if (getContactDisplayName(contact) != contact.username)
            Center(child: Text('(${contact.username})')),
          const SizedBox(height: 50),
          BetterListTile(
            icon: FontAwesomeIcons.solidComments,
            text: context.lang.contactViewMessage,
            onTap: () async {
              final group = await twonlyDB.groupsDao.getDirectChat(
                contact.userId,
              );
              if (group != null && context.mounted) {
                await context.push(Routes.chatsMessages(group.groupId));
              }
            },
          ),
          const Divider(),
          BetterListTile(
            icon: FontAwesomeIcons.pencil,
            text: context.lang.contactNickname,
            onTap: () async {
              final nickName = await showNicknameChangeDialog(context, contact);

              if (context.mounted && nickName != null && nickName != '') {
                final update = ContactsCompanion(nickName: Value(nickName));
                await twonlyDB.contactsDao.updateContact(
                  contact.userId,
                  update,
                );
              }
            },
          ),
          SelectChatDeletionTimeListTitle(
            groupId: getUUIDforDirectChat(
              widget.userId,
              userService.currentUser.userId,
            ),
          ),
          ContactLabelsSubtitleBuilder(
            contactId: contact.userId,
            builder: (context, subtitleWidget) {
              return BetterListTile(
                icon: FontAwesomeIcons.tag,
                text: context.lang.contactLabelsTitle,
                subtitle: subtitleWidget,
                onTap: () {
                  context.navPush(
                    SelectContactLabelsView(contactId: contact.userId),
                  );
                },
              );
            },
          ),
          const Divider(),
          RestoreFlameComp(
            contactId: widget.userId,
          ),
          VerificationExpansionTileComp(
            contact: contact,
          ),
          MutualGroupsExpansionTileComp(
            contact: contact,
          ),
          UserDiscoveryContactSettingsComp(
            contact: contact,
          ),
          const Divider(),
          BetterListTile(
            icon: FontAwesomeIcons.flag,
            text: context.lang.reportUser,
            onTap: () => handleReportUser(contact),
          ),
          BetterListTile(
            icon: FontAwesomeIcons.ban,
            text: context.lang.contactBlock,
            onTap: () => handleUserBlockRequest(contact),
          ),
          BetterListTile(
            icon: FontAwesomeIcons.userMinus,
            iconSize: 16,
            color: Colors.red,
            text: context.lang.contactRemove,
            onTap: () => handleUserRemoveRequest(contact),
          ),
          if (userService.currentUser.isDeveloper) ...[
            if (contact.signalVersion != SignalVersion.v2)
              BetterListTile(
                icon: FontAwesomeIcons.arrowsRotate,
                text: 'Update Connection to V2 (PQXDH)',
                onTap: () async {
                  final userData = await apiService.getUserById(contact.userId);
                  if (userData != null) {
                    await processSignalUserData(userData);
                    final updatedContact = await twonlyDB.contactsDao
                        .getContactById(contact.userId);
                    final isV2 =
                        updatedContact?.signalVersion == SignalVersion.v2;

                    if (context.mounted) {
                      showSnackbar(
                        context,
                        isV2
                            ? 'Connection updated to V2 successfully'
                            : 'Failed to update connection to V2',
                        level: isV2
                            ? SnackbarLevel.success
                            : SnackbarLevel.error,
                      );
                    }
                  }
                },
              ),
            const Divider(),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 12),
              child: Center(
                child: Text(
                  'Encryption: ${switch (contact.signalVersion) {
                    SignalVersion.v1 => 'Signal Protocol (v1)',
                    SignalVersion.v2 => 'PQXDH (v2)',
                  }}',
                  style: const TextStyle(color: Colors.grey),
                ),
              ),
            ),
          ],
        ],
      ),
    );
  }
}

Future<String?> showNicknameChangeDialog(
  BuildContext context,
  Contact contact,
) {
  final controller = TextEditingController(
    text: getContactDisplayName(contact),
  );

  return showDialog<String>(
    context: context,
    builder: (context) {
      return AlertDialog(
        title: Text(context.lang.contactNickname),
        content: TextField(
          controller: controller,
          autofocus: true,
          textCapitalization: TextCapitalization.words,
          decoration: InputDecoration(
            hintText: context.lang.contactNicknameNew,
          ),
        ),
        actions: <Widget>[
          TextButton(
            child: Text(context.lang.cancel),
            onPressed: () {
              Navigator.of(context).pop(); // Close the dialog
            },
          ),
          TextButton(
            child: Text(context.lang.ok),
            onPressed: () {
              Navigator.of(
                context,
              ).pop(controller.text); // Return the input text
            },
          ),
        ],
      );
    },
  );
}

Future<String?> showReportDialog(
  BuildContext context,
  Contact contact,
) {
  final controller = TextEditingController();

  return showDialog<String>(
    context: context,
    builder: (context) {
      return AlertDialog(
        title: Text(
          context.lang.reportUserTitle(getContactDisplayName(contact)),
        ),
        content: TextField(
          controller: controller,
          autofocus: true,
          textCapitalization: TextCapitalization.sentences,
          decoration: InputDecoration(hintText: context.lang.reportUserReason),
        ),
        actions: <Widget>[
          TextButton(
            child: Text(context.lang.cancel),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
          TextButton(
            child: Text(context.lang.ok),
            onPressed: () {
              Navigator.of(context).pop(controller.text);
            },
          ),
        ],
      );
    },
  );
}
