/*
 * @Author: wangyang 1147192855@qq.com
 * @Date: 2022-07-06 10:37:36
 * @LastEditors: wangyang 1147192855@qq.com
 * @LastEditTime: 2022-09-26 17:24:33
 * @FilePath: \marking_app\lib\pages\login\index.dart
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';

import 'package:dio/adapter.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:marking_app/common/config/request_config.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/utils/const_text.dart';
import 'package:marking_app/utils/index.dart';
import 'package:marking_app/utils/my_text.dart';
import 'package:marking_app/utils/request/rest_client.dart';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/common/model/user/user_info.dart';
import 'package:marking_app/common/model/user/user_login.dart';
import 'package:marking_app/common/model/user/user_login_params.dart';
import 'package:marking_app/provider/user_provider.dart';
import 'package:marking_app/routes/RouterManager.dart';

class TheLogin extends StatefulHookConsumerWidget {
  const TheLogin({Key? key}) : super(key: key);

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

class _TheLoginState extends ConsumerState<TheLogin> with CommonMixin {
  late Dio dio;
  late RestClient client;

  //添加证书
  setHttpsPEM() async {
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
      client.badCertificateCallback = (X509Certificate cert, String host, int port) {
        return true;
      };
    };
  }

  //文本输入框控制器
  late final TextEditingController _userNameController;
  late final TextEditingController _passwordController;

  late final FocusNode _pwdFocus; // 密码
  late final FocusNode _theFocus;

  bool keepPwd = false; // 记住密码
  bool readAgreement = true; // 阅读协议
  bool canLogin = true;
  bool hasNameVal = false;
  bool _isShowPwd = true;

  void _showPassword() {
    setState(() {
      _isShowPwd = !_isShowPwd;
    });
  }

  @override
  void initState() {
    Future(() {
      // 延迟更新 Provider
      ref.read(userTokenProvider.notifier).clean(); // 进入登录页先清空信息
    });

    super.initState();
    dio = Dio(
      BaseOptions(
        contentType: "application/json",
        connectTimeout: 8000,
        receiveTimeout: 8000,
      ),
    );
    dio.interceptors.add(LogInterceptor(responseBody: true, requestBody: true)); //添加日志

    setHttpsPEM();
    client = RestClient(dio, baseUrl: RequestConfig().loginBaseUrl);

    _userNameController = TextEditingController()..addListener(userNameListener);
    _passwordController = TextEditingController();
    _pwdFocus = FocusNode();
    _theFocus = FocusNode();
    FastData.getInstance().getUserPwd().then((value) {
      if (value == null || value == '') return;
      Map<String, dynamic> valMap = json.decode(value);
      setState(() {
        _passwordController.text = valMap['pwd'];
        _userNameController.text = valMap['account'];
        keepPwd = true;
      });
    });
  }

  void userNameListener() {
    String userName = _userNameController.text;
    int useNameLength = userName.length;
    bool hasNameValNew = useNameLength > 0;
    if (hasNameValNew != hasNameVal) toUpState(setState, () => hasNameVal = hasNameValNew, mounted);
    const isProd = bool.fromEnvironment('dart.vm.product');
    if (!isProd && useNameLength == 11) {
      _passwordController.text = userName.substring(useNameLength - 6);
    }
  }

  @override
  void dispose() {
    super.dispose();
    _userNameController
      ..removeListener(userNameListener)
      ..dispose();
    _passwordController.dispose();
    _pwdFocus.dispose();
    _theFocus.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onTap: () {
        FocusScope.of(context).requestFocus(_theFocus);
      },
      child: AnnotatedRegion(
        value: const SystemUiOverlayStyle(
          statusBarColor: Colors.transparent,
          systemNavigationBarIconBrightness: Brightness.light,
          statusBarIconBrightness: Brightness.light,
          statusBarBrightness: Brightness.dark,
        ),
        child: Scaffold(
          backgroundColor: Colors.transparent,
          resizeToAvoidBottomInset: false,
          body: Container(
              width: double.infinity,
              height: double.infinity,
              alignment: Alignment.center,
              decoration: const BoxDecoration(
                image: DecorationImage(
                  image: AssetImage('assets/images/login_bgi.png'),
                  fit: BoxFit.fill, // 完全填充
                ),
              ),
              child: SingleChildScrollView(
                child: Column(
                  children: [
                    Container(
                      width: 86.w,
                      height: 86.w,
                      alignment: Alignment.center,
                      child: SizedBox(
                        height: 86.w,
                        width: 86.w,
                        child: Image.asset('assets/images/logo.png', fit: BoxFit.cover),
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.h),
                      padding: EdgeInsets.only(top: 34.h, bottom: 16.h, left: 22.w, right: 22.w),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        border: Border.all(width: 1.w, color: Colors.white),
                        borderRadius: BorderRadius.all(Radius.circular(10.w)),
                        boxShadow: const [
                          BoxShadow(
                            color: Color.fromRGBO(46, 91, 255, 0.1),
                            offset: Offset.zero, //阴影y轴偏移量
                            blurRadius: 100, //阴影模糊程度
                            spreadRadius: 100, //阴影扩散程度
                          )
                        ],
                      ),
                      child: Column(children: [
                        TextField(
                          controller: _userNameController,
                          maxLines: 1,
                          maxLength: 20,
                          textInputAction: TextInputAction.next,
                          onEditingComplete: () {
                            FocusScope.of(context).requestFocus(_pwdFocus);
                          },
                          style: TextStyle(
                            color: const Color.fromRGBO(80, 87, 103, 1),
                            fontSize: 15.sp,
                          ),
                          decoration: InputDecoration(
                            hintText: "请输入账号",
                            hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
                            labelText: "账号",
                            labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
                            suffixIcon: !hasNameVal
                                ? null
                                : Transform.translate(
                                    offset: Offset(10, 10), // 根据原始组件的padding值来设置偏移量
                                    child: IconButton(
                                      alignment: Alignment.center,
                                      padding: EdgeInsets.zero,
                                      icon: Icon(
                                        Icons.highlight_off_sharp,
                                        color: Colors.grey,
                                        size: 16.r,
                                      ),
                                      onPressed: () {
                                        _userNameController.clear(); // 清空文本框内容
                                        _passwordController.clear();
                                      },
                                    ),
                                  ),
                          ),
                        ),
                        TextField(
                          focusNode: _pwdFocus,
                          controller: _passwordController,
                          keyboardType: TextInputType.number,
                          maxLines: 1,
                          obscureText: _isShowPwd, //隐藏密码显示
                          textInputAction: TextInputAction.go,
                          onSubmitted: (val) => toLogin(),
                          style: TextStyle(
                            color: const Color.fromRGBO(80, 87, 103, 1),
                            fontSize: 15.sp,
                          ),
                          decoration: InputDecoration(
                            hintText: "请输入密码",
                            suffix: GestureDetector(
                              onTap: _showPassword,
                              child: Icon(
                                Icons.remove_red_eye,
                                color: !_isShowPwd ? Theme.of(context).primaryColor : Colors.grey,
                              ),
                            ),
                            hintStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(153, 153, 153, 1)),
                            labelText: "密码",
                            isDense: true,
                            labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
                          ),
                        ),
                        SizedBox(
                          height: 12.h,
                        ),
                        Row(
                          children: [
                            Container(
                              width: 30.w,
                              padding: EdgeInsets.only(right: 10.w),
                              child: Checkbox(
                                activeColor: Theme.of(context).primaryColor,
                                checkColor: Colors.white,
                                value: keepPwd,
                                onChanged: (value) {
                                  FocusScope.of(context).requestFocus(_pwdFocus);
                                  FocusScope.of(context).requestFocus(_theFocus);
                                  setState(() {
                                    keepPwd = value ?? false;
                                  });
                                },
                              ),
                            ),
                            InkWell(
                              onTap: () {
                                FocusScope.of(context).requestFocus(_pwdFocus);
                                FocusScope.of(context).requestFocus(_theFocus);
                                setState(() => keepPwd = !keepPwd);
                              },
                              child: Text(
                                '记住密码',
                                style: TextStyle(
                                  fontSize: 14.sp,
                                  color: const Color.fromRGBO(148, 163, 182, 1),
                                ),
                              ),
                            ),
                          ],
                        ),
                        InkWell(
                          onTap: toLogin,
                          child: Container(
                            margin: EdgeInsets.symmetric(vertical: 10.h),
                            decoration: BoxDecoration(
                              color: canLogin ? const Color.fromRGBO(9, 105, 246, 1) : Colors.grey,
                              boxShadow: [
                                BoxShadow(
                                  color: const Color.fromRGBO(46, 91, 255, 0.5),
                                  offset: Offset(6.w, 10.h), //阴影y轴偏移量
                                  blurRadius: 14, //阴影模糊程度
                                  spreadRadius: 0.5, //阴影扩散程度
                                )
                              ],
                              borderRadius: BorderRadius.all(
                                Radius.circular(8.w),
                              ),
                            ),
                            alignment: Alignment.center,
                            width: double.infinity,
                            height: 50.h,
                            child: Text(
                              '登 录',
                              style: TextStyle(fontSize: 16.sp, color: Colors.white),
                            ),
                          ),
                        ),
                        Row(
                          children: [
                            Container(
                              width: 30.w,
                              padding: EdgeInsets.only(right: 10.w),
                              child: Checkbox(
                                activeColor: Colors.deepOrangeAccent,
                                checkColor: Colors.white,
                                value: readAgreement,
                                onChanged: (value) {
                                  FocusScope.of(context).requestFocus(_pwdFocus);
                                  FocusScope.of(context).requestFocus(_theFocus);
                                  setState(() {
                                    readAgreement = value ?? false;
                                  });
                                },
                              ),
                            ),
                            InkWell(
                              onTap: () {
                                RouterManager.router.navigateTo(
                                  context,
                                  '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}',
                                  transition: getTransition(),
                                );
                              },
                              child: quickText('请仔细阅读', size: 13.sp),
                            ),
                            InkWell(
                              onTap: () {
                                RouterManager.router.navigateTo(
                                  context,
                                  '${RouterManager.agreementPath}?type=${AGREEMENT_KEY.USER_AGREEMENT.name}',
                                  transition: getTransition(),
                                );
                              },
                              child: const Text(
                                '《用户协议》',
                                style: TextStyle(color: Colors.deepOrangeAccent),
                              ),
                            ),
                          ],
                        ),
                      ]),
                    )
                  ],
                ),
              )),
        ),
      ),
    );
  }

  // 前往登录
  void toLogin() async {
    if (!canLogin) return;

    setState(() => canLogin = false);

    void toMsg(msg) {
      ToastUtils.showError(msg);
      setState(() => canLogin = true);
    }

    FocusScope.of(context).requestFocus(_theFocus);

    String userName = _userNameController.text.trim();
    String userPwd = _passwordController.text.trim();
    if (userName == '') return toMsg('请填写用户账号');
    if (userPwd == '') return toMsg('请填写密码再试');
    if (!readAgreement) return toMsg('请阅读用户协议');

    String userPwdMd5 = CommonUtils.generateMD5(userPwd);
    EasyLoading.show(status: 'loading...');
    try {
      BaseStructureResult<dynamic> resultData = await client.toLogin(UserLoginParams(userName, userPwdMd5));
      UserLogin? userData =
          resultData.code == 200 && resultData.data != null ? UserLogin.fromJson(resultData.data) : null;
      if (resultData.code != 200 || userData?.accessToken == null || userData?.accessToken == '') {
        return toMsg(resultData.message ?? '登录失败，请重试');
      }

      FastData fastData = FastData.getInstance();
      fastData.setToken(userData!.accessToken);

      BaseStructureResult<UserInfo> userRes = await client.getUserInfo('Bearer ${userData.accessToken}');
      if (userRes.code != 200 || userRes.data == null) {
        throw Exception('登录失败，请重试');
      }

      fastData.setUser(userRes.data!).then((value) {
        // 记住密码
        if (keepPwd) {
          fastData.setUserPwdAndAccount({'pwd': userPwd, 'account': userName});
        }
        // 更新
        ref.read(userProvider.notifier).initUserInfo();
        ref.read(userTokenProvider.notifier).initToken();

        // 跳转登录页
        RouterManager.router.navigateTo(context, RouterManager.root, clearStack: true, transition: getTransition());
      });
    } catch (e) {
      toPrint(val: e.toString());
      String? msg;
      if (e is DioError) {
        DioErrorType errorType = e.type;
        switch (errorType) {
          case DioErrorType.connectTimeout:
            msg = '连接超时，请检查网络再重试';
            break;
          case DioErrorType.sendTimeout:
            msg = '发送时间超时，请重试';
            break;
          case DioErrorType.receiveTimeout:
            msg = '接收数据超时，请重试';
            break;
          case DioErrorType.response:
            // TODO: Handle this case.
            break;
          case DioErrorType.cancel:
            // TODO: Handle this case.
            break;
          case DioErrorType.other:
            // TODO: Handle this case.
            break;
        }
      }
      FastData.getInstance().cleanShared();
      return toMsg(msg ?? '登录失败，请重试');
    } finally {
      EasyLoading.dismiss();
    }
  }
}
