import 'dart:convert';
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';

import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/card_data.dart';
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/BankService.dart';
import 'package:aman_kassa_flutter/core/services/ForteService.dart';
import 'package:aman_kassa_flutter/core/services/DataService.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
import 'package:aman_kassa_flutter/widgets/fields/input_field.dart';
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';

import '../../core/models/aman_dao.dart';
import '../../core/models/card_data.dart';
import '../../core/models/card_data.dart';
import 'forte_pos_service.dart';

class PaymentView extends StatefulWidget {
  final PaymentModel model;

  const PaymentView({Key? key, required this.model}) : super(key: key);

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

class _PaymentViewState extends State<PaymentView> {
  final GlobalKey<State> _keyLoader = new GlobalKey<State>();
  final DataService _dataService = locator<DataService>();
  final DialogService _dialogService = locator<DialogService>();
  dynamic _bankService;
  final NavigatorService _navigatorService = locator<NavigatorService>();
  final TextEditingController _iinController  = new TextEditingController();
  final TextEditingController _ticketNumberController = new TextEditingController();
  late bool isBusy;
  late bool isBankApiAccess;

  var height = AppBar().preferredSize.height;

  @override
  void initState() {
    super.initState();
    isBusy = false;
    isBankApiAccess = false;
    _bankInit();
  }

  @override
  void dispose() {
    _iinController.dispose();
    _ticketNumberController.dispose();
    super.dispose();
  }

  _bankInit() async {
    BankState? state = Redux.store?.state.bankState;

    print(state?.toJson());

    if (state?.sessionType == 'Halyk' && state?.session != null) {
      _bankService = locator<BankService>();
    } else if (state?.sessionType == 'Forte' && state?.session != null) {
      _bankService = locator<ForteService>();
    } else {
      setState(() {
        isBankApiAccess = false;
      });
      return;
    }

    int version = await _bankService.version();
    setState(() {
      isBankApiAccess = version >= _bankService.sdkVersion;
    });
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        if (!isBusy) Navigator.pop(context);
        return new Future(() => false);
      },
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: whiteColor,
          elevation: 0,
          leading: IconButton(
            icon: Icon(Icons.arrow_back_ios),
            color: Colors.black87,
            onPressed: () => Navigator.pop(context),
          ),
          title: Text(
            dataTitle(),
            style: TextStyle(color: Colors.black87),
          ),
        ),
        body: SingleChildScrollView(
          child: SizedBox(
            height: ScreenUtil().screenHeight - ScreenUtil().statusBarHeight - height,
            child: Container(
              padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 12.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    dataText(),
                    style: TextStyle(
                        fontWeight: FontWeight.bold,
                        color: Colors.black26,
                        fontSize: 15),
                  ),
                  buildStoreConnector(),
                  verticalSpaceLarge,
                  _buildBodyContent(),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  String dataTitle() =>
      widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';

  String dataText() =>
      widget.model.operationType == OperationTypePay
          ? 'К оплате'
          : 'К возврату';

  StoreConnector buildStoreConnector() {
    if (widget.model.mode == SettingModeCalc) {
      return StoreConnector<AppState, CalcState>(
          converter: (store) => store.state.calcState!,
          builder: (_, vm) {
            return Text('${totalCalc(vm.calcItems!)} тнг',
                style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: Colors.black87,
                    fontSize: 35));
          });
    }
    return StoreConnector<AppState, KassaState>(
        converter: (store) => store.state.kassaState!,
        builder: (_, vm) {
          return Text('${totalKassa(vm.kassaItems!)} тнг',
              style: TextStyle(
                  fontWeight: FontWeight.bold,
                  color: Colors.black87,
                  fontSize: 35));
        });
  }

  bool get _isReturn => widget.model.operationType == OperationTypeReturn;

  bool _canProceed() {
    if (_isReturn && _ticketNumberController.text.trim().isEmpty) {
      return false;
    }
    return true;
  }

  void _onPaymentPressed(String type, CardData? cardData) {
    if (!_canProceed()) {
      _dialogService.showDialog(
          description: 'Введите фискальный признак для выполнения возврата.');
      return;
    }
    pressPayment(type, cardData);
  }

  Expanded _buildBodyContent() {
    return Expanded(
      child: Column(
        children: <Widget>[
          TextField(
            keyboardType: TextInputType.number,
            controller: _iinController,
            maxLength: 12,
            decoration: InputDecoration(
                labelText: 'ИИН Покупателя', hintText: "Введите ИИН покупателя"),
          ),
          if (_isReturn)
            TextField(
              keyboardType: TextInputType.text,
              controller: _ticketNumberController,
              decoration: InputDecoration(
                  labelText: 'Фискальный признак *',
                  hintText: 'Введите фискальный признак'),
            ),
          if (_isReturn) verticalSpaceSmall,
          Container(
            height: 150,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                Expanded(
                    child: BusyButton(
                      title: 'Оплатить картой',
                      onPressed: () {
                        _onPaymentPressed('card', null);
                      },
                      mainColor: primaryColor,
                    )),
                horizontalSpaceSmall,
                Expanded(
                    child: BusyButton(
                      title: 'Мобильный',
                      onPressed: () {
                        _onPaymentPressed('mobile', null);
                      },
                      mainColor: redColor,
                    )),
                horizontalSpaceSmall,
                Expanded(
                    child: BusyButton(
                      title: 'Наличными',
                      onPressed: () {
                        _onPaymentPressed('cash', null);
                      },
                      mainColor: greenColor,
                    )),
              ],
            ),
          ),
          verticalSpaceLarge,
          _nfsButtonRender(),
          verticalSpaceSmall,
          Expanded(
            child: Container(),
          ),
          Container(
              child: BusyButton(
                title: 'Отмена',
                onPressed: () {
                  Navigator.pop(context);
                },
                mainColor: redColor,
              )),
        ],
      ),
    );
  }

  Widget _nfsButtonRender() {
    if (!isBankApiAccess || widget.model.operationType != OperationTypePay) {
      return Container();
    }
    return StoreConnector<AppState, AppState>(
        converter: (store) => store.state,
        builder: (_, _state) {
          BankState state = _state.bankState!;
          double _total;
          if (widget.model.mode == SettingModeCalc) {
            String value = totalCalc(_state.calcState!.calcItems!);
            _total = double.parse(value);
          } else {
            String value = totalKassa(_state.kassaState!.kassaItems!);
            _total = double.parse(value);
          }

          if (state.password == null || state.login == null ||
              state.password!.length < 1 || state.login!.length < 1) {
            return Container();
          }
          final bool isForteSessionActive = state.sessionType == 'Forte';

          final String imageAsset = isForteSessionActive
              ? 'assets/images/fortepos.png'
              : 'assets/images/halykpos.png';
          final Color sessionColor = isForteSessionActive ? forteColor : halykColor;
          final Future<AmanDao<CardData>> Function(double) paymentMethod =
          isForteSessionActive ? paymentFortePos : paymentHalykPos;

          return InkWell(
            onTap: isBusy ?
                () {} :
                () async {
              var today = new DateTime.now();
              var yesterday = today.subtract(new Duration(days: 1));
              if (Redux.store!.state.userState == null
                  || Redux.store!.state.userState!.smena == null
                  || Redux.store!.state.userState!.smena!.startedAt == null
                  || yesterday.isAfter(
                      Redux.store!.state.userState!.smena!.startedAt!)) {
                _dialogService.showDialog(
                    description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
                return;
              }
              setState(() {
                isBusy = true;
              });

              try {
                await Redux.store!.dispatch(changePinSkipFromSetting(true));
                AmanDao<CardData> data = await paymentMethod(_total);
                if (data.success == true) {
                  pressPayment('card', data.data);
                } else {
                  _dialogService.showDialog(description: data.msg ?? '');
                }
              } finally {
                await Redux.store!.dispatch(changePinSkipFromSetting(false));
                setState(() {
                  isBusy = false;
                });
              }
            },
            splashColor: halykColor.withOpacity(0.4),
            borderRadius: BorderRadius.circular(10.0),
            highlightColor: halykColor.withOpacity(0.1),
            child: SizedBox(
              width: ScreenUtil().setSp(80.0),
              height: ScreenUtil().setSp(80.0),
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(color: Colors.white),
                  borderRadius: BorderRadius.circular(10.0),
                  image: DecorationImage(
                      image: AssetImage(imageAsset),
                      fit: BoxFit.fitWidth
                  ),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.grey.withOpacity(0.5),
                      spreadRadius: 5,
                      blurRadius: 7,
                      offset: Offset(0, 3), // changes position of shadow
                    ),
                  ],
                ),
              ),
            ),
          );
        }
    );
  }

  pressPayment(String type, CardData? cardData) async {
    setState(() {
      isBusy = true;
    });
    Dialogs.showLoadingDialog(context, _keyLoader);
    try {
      AppState _state = Redux.store!.state;
      String _token = _state.userState!.user!.token!;
      String _tradeType = _state.settingState!.tradeType!;
      String _mode = _state.settingState!.mode!;
      if (_mode == SettingModeCalc) {
        _tradeType = SettingTradeTypeGood;
      }
      List<ProductDao> kassaItems = _state.kassaState!.kassaItems!;
      List<CalcModel> calcItems = _state.calcState!.calcItems!;
      Response<dynamic>? response = await _dataService.sellOrReturn(
          token: _token,
          kassaItems: kassaItems,
          paymentType: type,
          operationType: widget.model.operationType,
          tradeType: _tradeType,
          calcItems: calcItems,
          mode: _mode,
          cardData: cardData,
          contragent: _iinController.text,
          ticketNumber: _isReturn ? _ticketNumberController.text.trim() : null,
      );
      setState(() {
        isBusy = false;
      });
      if (response != null) {
        if (response.operation) {
          String message = response.body['message'];
          String check = response.body['check'];
          var checkText = response.body['check_text'];
          String url = response.body['link'];
          print('url : $url');
          if (_mode == SettingModeCalc) {
            Redux.store!.dispatch(cleanCalcItems);
          } else if (_mode == SettingModeKassa) {
            Redux.store!.dispatch(cleanKassaItems);
          }
          Redux.store!.dispatch(checkMoney);
          Redux.store!.dispatch(openSmenaPseudo);
          Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
          _navigatorService.pop();
          _navigatorService.push(ImageShowRoute,
              arguments: ImageShowModel(data: new CheckImageModal(
                  base64Data: check,
                  textData: checkText != null ? jsonEncode(checkText) : null),
                  title: message,
                  url: url));
        } else if (!response.operation &&
            ![401, 402, 403, 412, 500].contains(response.status)) {
          Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
          _dialogService.showDialog(description: response.body['message']);
        } else if (!response.operation && response.body['message'] != null) {
          Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
          _dialogService.showDialog(description: response.body['message']);
        } else {
          Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
        }
      } else {
        Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
      }
    } catch (e) {
      print(e);
      Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
    } finally {
      //Navigator.of(context, rootNavigator: true).pop();
      setState(() {
        isBusy = false;
      });
    }
  }

  String totalKassa(List<ProductDao> kassaItems) {
    num total = 0.0;
    kassaItems.forEach((element) {
      total += element.total == null ? 0.0 : element.total.toDouble();
    });
    return total.toString();
  }

  String totalCalc(List<CalcModel> items) {
    num total = 0.0;
    items.forEach((element) {
      if (element.operation == Calculations.MULTIPLY) {
        double num1 = element.num1 == null ? 0.0 : double.parse(element.num1);
        double num2 = element.num2 == null ? 0.0 : double.parse(element.num2!);
        total += num1 * num2;
      } else {
        total += element.num1 == null ? 0.0 : double.parse(element.num1);
      }
    });
    return total.toString();
  }
}

class PaymentModel {
  String operationType;
  String mode;
  Voucher? voucher;
  CardData? cardData;

  PaymentModel(
      {required this.mode, required this.operationType, this.voucher, this.cardData});
}
