import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:get/get.dart';
import 'package:injectable/injectable.dart';
import 'package:location/data/consts/error_code.dart';
import 'package:location/data/repositories/friends_repository.dart';
import 'package:location/module/add_friend/add_friend_locate_result_dialog.dart';
import 'package:location/module/login/login_page.dart';
import 'package:location/module/member/member_page.dart';
import 'package:location/resource/string.gen.dart';
import 'package:location/utils/common_expand.dart';
import 'package:location/utils/http_handler.dart';
import 'package:location/utils/permission_util.dart';
import 'package:location/utils/toast_util.dart';
import 'package:permission_handler/permission_handler.dart';

import '../../../base/base_controller.dart';
import '../../data/repositories/account_repository.dart';
import '../../dialog/common_confirm_dialog_impl.dart';
import '../../sdk/wechat/wechat_share_util.dart';
import '../../utils/de_bounce.dart';

@injectable
class AddFriendDialogController extends BaseController {
  final FriendsRepository friendsRepository;

  final TextEditingController etController = TextEditingController();

  AddFriendDialogController(this.friendsRepository);

  final RxString _phone = RxString('');

  String get phone => _phone.value;

  final Debounce _saveDebounce = Debounce(debounceTime: 500);

  @override
  void onReady() {
    super.onReady();
    etController.addListener(() {
      _phone.value = etController.text;
    });
  }

  void onAddFriendClick() {
    FocusScope.of(Get.context!).unfocus();
    if (!RegExp(r'^1\d{10}$').hasMatch(phone)) {
      ToastUtil.show(StringName.loginPrintPhoneVerification);
      return;
    }
    showAddFriendConfirmDialog(onConfirm: () {
      _saveDebounce.onClick(() {
        _requestAddFriend();
      });
    });
  }

  void _requestAddFriend() {
    AccountRepository accountRepository = AccountRepository.getInstance();
    if (accountRepository.memberIsExpired()) {
      AddFriendLocateResultDialog.show(confirmOnTap: () {
        FocusScope.of(Get.context!).unfocus();
        MemberPage.start(enterTyp: MemberPageType.addFriendToEnter);
      });
    } else {
      friendsRepository.addFriendRequest(phone).then((_) {
        ToastUtil.show(StringName.requestSuccess);
        Get.back();
      }).catchError((error) {
        if (accountRepository.memberIsExpired()) {
          AddFriendLocateResultDialog.show(confirmOnTap: () {
            FocusScope.of(Get.context!).unfocus();
            MemberPage.start(enterTyp: MemberPageType.addFriendToEnter);
          });
        } else {
          if (error is ServerErrorException) {
            if (error.code == ErrorCode.noLoginError) {
              _showNoLoginDialog();
            } else if (error.code == ErrorCode.friendNotRegistered) {
              _showNotRegisteredDialog();
            } else if (error.code == ErrorCode.alreadyInFriendList) {
              ToastUtil.show(StringName.addFriendAdded);
            } else if (error.code == ErrorCode.friendRequestSent) {
              ToastUtil.show(StringName.sendAddFriendSuccess);
            } else if (error.code == ErrorCode.cannotAddSelf) {
              ToastUtil.show(StringName.addFriendOwn);
            } else {
              ToastUtil.show(StringName.requestFail);
            }
          } else {
            ToastUtil.show(StringName.requestFail);
          }
        }
      });
    }
  }

  void _showNotRegisteredDialog() {
    showNotRegisteredDialog(onConfirm: () {
      _shareToWechat();
    });
  }

  void shareWxClick() {
    showAppShareDialog(onConfirm: () {
      _shareToWechat();
    });
  }

  void _shareToWechat() async {
    WechatShareUtil.shareWebPage().catchError((error) {
      ToastUtil.show(error.toString().replaceFirst("Exception: ", ""));
    });
  }

  void _showNoLoginDialog() {
    showLoginDialog(onConfirm: () {
      LoginPage.start();
    });
  }

  void onSelectContactClick() async {
    bool isGranted = await PermissionUtil.checkPermission(Permission.contacts);
    if (!isGranted) {
      requestContactsPermissionDialog(onConfirm: () async {
        isGranted = await PermissionUtil.requestPermission(Permission.contacts);
        if (isGranted) {
          _goContact();
        } else {
          ToastUtil.show(StringName.permissionRequestFail);
        }
      });
    } else {
      _goContact();
    }
  }

  void _goContact() async {
    FocusScope.of(Get.context!).unfocus();
    final contact = await FlutterContacts.openExternalPick();
    if (contact != null) {
      final phones = contact.phones;
      if (phones.isNotEmpty) {
        etController.text = phones.first.number.trimAll();
      }
    }
  }

  @override
  void onClose() {
    super.onClose();
    etController.dispose();
  }
}
