import 'dart:async';

import 'package:fis_i18n/i18n.dart';
import 'package:fis_ui/index.dart';
import 'package:fis_ui/interface/interactive_container.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/pages/auth/widgets/text_field.dart';
import 'package:flyinsono/pages/element_static.dart';
import 'package:get/get.dart';
import 'package:fis_theme/theme.dart';

/// 验证码表单栏控制器
class VerificationCodeFieldController extends GetxController {
  VerificationCodeFieldController({
    this.countDown = 60,
  });

  final int countDown;

  Timer? _timer;
  bool _hasSent = false;

  final _seconds = 0.obs;
  final _isFetching = false.obs;
  final Rx<String> _btnText = Rx('');

  /// 倒计时读秒
  int get seconds => _seconds.value;
  set seconds(int val) => _seconds(val);

  /// 是否正在获取验证码
  bool get isFetching => _isFetching.value;
  set isFetching(bool val) => _isFetching(val);

  /// 按钮文字
  String get btnText => setBtnText();
  set btnText(String val) => _btnText(val);

  /// 按钮是否禁用
  bool get isBtnDisabled => isFetching || seconds > 0;

  /// 开启倒计时
  startCountDown() {
    _hasSent = true;
    seconds = countDown;
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      seconds--;
      if (seconds == 0) {
        timer.cancel();
      }
    });
  }

  String setBtnText() {
    if (seconds > 0) {
      _btnText.value =
          i18nBook.auth.sendVerificationCodeTimer.translate([seconds]);
    } else {
      _btnText.value = _hasSent
          ? i18nBook.auth.resendVerificationCode.t
          : i18nBook.auth.sendVerificationCode.t;
    }
    return _btnText.value;
  }

  ///重置
  void reset() {
    if (_seconds.value == 0) {
      _timer?.cancel();
      _hasSent = false;
      _isFetching.value = false;
      setBtnText();
    }
  }

  @override
  void onClose() {
    _timer?.cancel();
    _timer = null;
    super.onClose();
  }
}

/// 验证码表单栏
class VerificationCodeField extends StatelessWidget
    implements FInteractiveContainer {
  VerificationCodeField({
    Key? key,
    this.tag,
    this.pageName = 'VerificationCodeField',
    required this.fetchCodeFunc,
    this.textController,
    this.textFocusNode,
    this.onTextChanged,
    this.disabled = false,
    this.inError = false,
  }) : super(key: key);

  @override
  final String pageName;
  final String? tag;
  final bool disabled;
  final Future<bool> Function() fetchCodeFunc;
  final TextEditingController? textController;
  final FocusNode? textFocusNode;
  final ValueChanged<String>? onTextChanged;
  final bool inError;

  @override
  FWidget build(BuildContext context) {
    if (kIsMobile)
      return _MobileLayout(
        businessParent: this,
        tag: tag,
        disabled: disabled,
        fetchCodeFunc: fetchCodeFunc,
        textController: textController,
        textFocusNode: textFocusNode,
        onTextChanged: onTextChanged,
        inError: inError,
      );
    final textField = _buildTextField(context);
    final button = _buildButton(context);
    return FFormField(builder: (state) {
      return FRow(
        children: [
          FExpanded(
            flex: 1,
            child: FContainer(
              margin: EdgeInsets.only(right: 5),
              child: textField,
            ),
          ),
          button,
        ],
      );
    });
  }

  FWidget _buildButton(BuildContext context) {
    final controller = Get.find<VerificationCodeFieldController>(tag: tag);
    final textStyle = TextStyle(
      fontSize: 14.sp,
      color: Colors.white,
      height: 1,
    );
    final btnStyle = ElevatedButton.styleFrom(
      elevation: 0,
      padding: EdgeInsets.symmetric(vertical: 18.sp, horizontal: 16.sp),
      minimumSize: Size(120, 56.sp),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(8.sp),
      ),
    );
    final onBtnTap = () {
      controller.isFetching = true;
      fetchCodeFunc().then((value) {
        controller.isFetching = false;
        if (value) {
          controller.startCountDown();
        }
      });
    };
    return FObx(() {
      final isDisabled = disabled || controller.isBtnDisabled;
      final text = controller.btnText;
      return FElevatedButton(
        businessParent: this,
        onPressed: isDisabled ? null : onBtnTap,
        name: text,
        child: FText(
          text,
          style: textStyle,
        ),
        style: btnStyle,
      );
    });
  }

  FWidget _buildTextField(BuildContext context) {
    final border = FBorderTextFormField.createDesktopBorder(inError);

    final textField = FTextField(
      controller: textController,
      focusNode: textFocusNode,
      maxLength: 4,
      style: TextStyle(fontSize: 18.sp),
      keyboardType: TextInputType.number,
      inputFormatters: [PageInputFormatters.number],
      decoration: InputDecoration(
        hintText: i18nBook.auth.hint4VerificationCode.t,
        fillColor: TEXT_FIELD_FILL_COLOR,
        filled: true,
        hintStyle: TextStyle(
          fontSize: 16.sp,
          color: Colors.black54,
        ),
        alignLabelWithHint: true,
        counterText: '',
        isDense: true,
        contentPadding: FBorderTextFormField.createDesktopContentPadding(),
        enabledBorder: border,
        focusedBorder: border,
      ),
      onChanged: onTextChanged,
    );
    return textField;
  }
}

/// 验证码表单栏
class _MobileLayout extends StatelessWidget implements FWidget {
  _MobileLayout({
    this.tag,
    required this.fetchCodeFunc,
    this.textController,
    this.textFocusNode,
    this.onTextChanged,
    this.disabled = false,
    this.inError = false,
    required this.businessParent,
  });

  ///父级节点
  final FInteractiveContainer businessParent;
  final String? tag;
  final bool disabled;
  final Future<bool> Function() fetchCodeFunc;
  final TextEditingController? textController;
  final FocusNode? textFocusNode;
  final ValueChanged<String>? onTextChanged;
  final bool inError;

  @override
  FWidget build(BuildContext context) {
    final textField = _buildTextField(context);
    final button = _buildButton(context);
    return FFormField(builder: (state) {
      return FRow(
        children: [
          FExpanded(
            flex: 1,
            child: FContainer(
              margin: EdgeInsets.only(right: 5.sp),
              child: textField,
            ),
          ),
          if (kIsWeb)
            button
          else
            FContainer(
              height: 32.w,
              child: button,
            ),
        ],
      );
    });
  }

  FWidget _buildButton(BuildContext context) {
    final controller = Get.find<VerificationCodeFieldController>(tag: tag);
    final textStyle = TextStyle(
      fontSize: 14.sp,
      color: Colors.white,
    );
    final btnStyle = ElevatedButton.styleFrom(
      elevation: 0,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(4.sp),
      ),
      minimumSize: Size.fromWidth(100.sp),
    );
    final onBtnTap = () {
      controller.isFetching = true;
      fetchCodeFunc().then((value) {
        controller.isFetching = false;
        if (value) {
          controller.startCountDown();
        }
      });
    };
    return FObx(() {
      final isDisabled = disabled || controller.isBtnDisabled;
      final text = controller.btnText;
      return FElevatedButton(
        onPressed: isDisabled ? null : onBtnTap,
        name: text,
        businessParent: this.businessParent,
        child: FText(
          controller.btnText,
          style: textStyle,
        ),
        style: btnStyle,
      );
    });
  }

  FWidget _buildTextField(BuildContext context) {
    final border = OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(4.sp)),
      borderSide: BorderSide(
        color: inError
            ? TEXT_FIELD_BORDER_ERROR_COLOR
            : FTheme.ins.data.colorScheme.line,
      ),
    );

    final textField = FTextField(
      controller: textController,
      focusNode: textFocusNode,
      maxLength: 4,
      keyboardType: TextInputType.number,
      decoration: InputDecoration(
        hintText: i18nBook.auth.hint4VerificationCode.t,
        fillColor: TEXT_FIELD_FILL_COLOR,
        filled: true,
        hintStyle: TextStyle(
          fontSize: 12,
          color: Colors.black54,
        ),
        alignLabelWithHint: true,
        counterText: '',
        isDense: true,
        contentPadding: EdgeInsets.symmetric(vertical: 8.sp, horizontal: 26.sp),
        enabledBorder: border,
        focusedBorder: border,
      ),
      onChanged: onTextChanged,
    );
    return textField;
  }
}
