import 'dart:async';

import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../../../common/models/index.dart';
import '../../../../../common/routers/index.dart';
import '../../../../../common/services/index.dart';
import '../../../../../common/utils/index.dart';
import 'gesture_type.dart';
import 'index.dart';

class GestureUnlockController extends GetxController
    with GetSingleTickerProviderStateMixin {
  GestureUnlockController();

  final state = GestureUnlockState();

  final gestureBoxSize = 300.0;

  late final AnimationController _animationController = AnimationController(
      vsync: this, duration: const Duration(milliseconds: 500));
  late CurvedAnimation curvedAnimation =
      CurvedAnimation(curve: Curves.easeIn, parent: _animationController);
  late Animation<double> animation =
      Tween(begin: 0.0, end: 10.0).animate(curvedAnimation)
        ..addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            _animationController.reset();
          }
        });
  GestureType gestureType = GestureType.unlock; // 手势类型，unlock 解锁，setup 设置密码

  String firstPwd = ""; // 第一次输入的密码

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    final map = Get.arguments;
    if (map != null) {
      gestureType = map['type'] ?? GestureType.unlock;
    }
    initNinePointPosition();
    if (gestureType == GestureType.unlock) {
      state.closeBtnVisible = false;
      state.titleText = "account_safe_gesture_unlock_label_unlock".tr;
    } else {
      state.closeBtnVisible = true;
      state.titleText = "account_safe_gesture_unlock_label_setup".tr;
    }
    super.onReady();
  }

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

  /// 初始化九宫格点的位置
  void initNinePointPosition() {
    // 上面
    state.ninePointList.add(
        GesturePassWord(1, Offset(-gestureBoxSize / 3, -gestureBoxSize / 3)));
    state.ninePointList.add(GesturePassWord(2,
        Offset(-gestureBoxSize / 3 + gestureBoxSize / 3, -gestureBoxSize / 3)));
    state.ninePointList.add(GesturePassWord(
        3,
        Offset(-gestureBoxSize / 3 + gestureBoxSize / 3 * 2,
            -gestureBoxSize / 3)));
    // 中间
    state.ninePointList.add(GesturePassWord(4, Offset(-gestureBoxSize / 3, 0)));
    state.ninePointList.add(GesturePassWord(
        5, Offset(-gestureBoxSize / 3 + gestureBoxSize / 3, 0)));
    state.ninePointList.add(GesturePassWord(
        6, Offset(-gestureBoxSize / 3 + gestureBoxSize / 3 * 2, 0)));
    // 上面
    state.ninePointList.add(
        GesturePassWord(7, Offset(-gestureBoxSize / 3, gestureBoxSize / 3)));
    state.ninePointList.add(GesturePassWord(8,
        Offset(-gestureBoxSize / 3 + gestureBoxSize / 3, gestureBoxSize / 3)));
    state.ninePointList.add(GesturePassWord(
        9,
        Offset(
            -gestureBoxSize / 3 + gestureBoxSize / 3 * 2, gestureBoxSize / 3)));
  }

  double errorPwdAnimationValue() {
    double x = animation.value; // 变化速度 0-10,
    double d = x - x.truncate(); // 获取这个数字的小数部分
    double? y;
    if (d <= 0.5) {
      y = 2 * d;
    } else {
      y = 1 - 2 * (d - 0.5);
    }
    return y * 20;
  }

  ///手指按下触发
  void judgeZone(Offset src) {
    /// 循环所有的点
    for (int i = 0; i < state.ninePointList.length; i++) {
      var srcTranslate =
          src.translate(-gestureBoxSize / 2, -gestureBoxSize / 2);
      // 判断手指按的位置是否在点的区域
      if (_judgeCircleArea(srcTranslate, state.ninePointList[i].offset, 30)) {
        // 有点 判断是否已添加过
        for (int j = 0; j < state.gesturePassWords.length; j++) {
          if (state.gesturePassWords[j] == state.ninePointList[i]) {
            // 已添加过
            return;
          }
        }
        // 未添加过
        state.gesturePassWords.add(state.ninePointList[i]);
        return;
      }
    }
    // 无点
  }

  ///判断出是否在某点的半径为r圆范围内
  bool _judgeCircleArea(Offset src, Offset dst, double r) =>
      (src - dst).distance <= r;

  void onPanUpdate(Offset offset) {
    // 移动
    judgeZone(offset);
    if (state.gesturePassWords.isNotEmpty) {
      state.currentOffset.value =
          offset.translate(-gestureBoxSize / 2, -gestureBoxSize / 2);
    }
  }

  void onPanEnd() {
    if (gestureType == GestureType.unlock) {
      _checkPassword();
    } else {
      _setPassword();
    }
  }

  _setPassword() {
    String pwd = "";
    for (int i = 0; i < state.gesturePassWords.length; i++) {
      pwd += state.gesturePassWords[i].num.toString();
    }
    if (firstPwd.isEmpty) {
      // 第一次设置密码
      if (pwd.length < 3) {
        _setError('account_safe_gesture_unlock_error_setup_less_than_four'.tr, 'account_safe_gesture_unlock_label_setup'.tr);
      } else {
        firstPwd = pwd;
        state.gesturePassWords.clear();
        state.currentOffset.value = null;
        state.titleText = "account_safe_gesture_unlock_label_setup_repeat".tr;
      }
    } else {
      if (pwd == firstPwd) {
        setupPwd(pwd);
      } else {
        firstPwd = "";
        _setError('account_safe_gesture_unlock_error_setup_not_match'.tr, 'account_safe_gesture_unlock_label_setup'.tr);
      }
    }
  }

  _checkPassword() {
    String pwd = "";
    for (int i = 0; i < state.gesturePassWords.length; i++) {
      pwd += state.gesturePassWords[i].num.toString();
    }
    if (pwd.isEmpty) {
      return;
    }
    final pwdStore = SharedPreferenceService.to.getString(SharedPreferenceService.appGestureUnlockAuthKey);
    if (pwd.isNotEmpty && pwdStore != pwd) {
      _setError('account_safe_gesture_unlock_error_check_pwd'.tr, 'account_safe_gesture_unlock_label_unlock'.tr);
    } else {
      // 密码正确 进入首页
      Get.offNamed(O2OARoutes.home);
    }
  }

  _setError(String titleText, String resetTitleText) {
    state.color = Colors.red;
    Timer(const Duration(milliseconds: 500), () {
      state.gesturePassWords.clear();
      state.currentOffset.value = null;
      state.color = Colors.blue;
      state.titleText = resetTitleText;
      state.titleTextColor.value = null;
    });
    // 密码错误 触发动画
    _animationController.forward();
    state.titleText = titleText;
    state.titleTextColor.value = Colors.red;
  }

  Future<void> setupPwd(String pwd) async {
    await SharedPreferenceService.to
        .putString(SharedPreferenceService.appGestureUnlockAuthKey, pwd);
    Loading.toast("account_safe_gesture_unlock_toast_success".tr);
    closePage();
  }

  void closePage() {
    Get.back();
  }
}
