import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sixam_mart_delivery/features/my_account/domain/models/withdraw_method_model.dart';
import 'package:sixam_mart_delivery/features/disbursement/domain/models/disbursement_method_model.dart' as disburse;
import 'package:sixam_mart_delivery/features/disbursement/domain/models/disbursement_report_model.dart' as report;
import 'package:sixam_mart_delivery/common/widgets/custom_dropdown_widget.dart';
import 'package:sixam_mart_delivery/common/widgets/custom_snackbar_widget.dart';
import 'package:sixam_mart_delivery/features/disbursement/domain/services/disbursement_service_interface.dart';
import 'package:sixam_mart_delivery/features/profile/controllers/profile_controller.dart';

class DisbursementController extends GetxController implements GetxService {
  final DisbursementServiceInterface disbursementServiceInterface;
  DisbursementController({required this.disbursementServiceInterface});

  bool _isLoading = false;
  bool get isLoading => _isLoading;

  bool _isDeleteLoading = false;
  bool get isDeleteLoading => _isDeleteLoading;

  int? _selectedMethodIndex = 0;
  int? get selectedMethodIndex => _selectedMethodIndex;

  List<DropdownItem<int>> _methodList = [];
  List<DropdownItem<int>> get methodList => _methodList;

  List<TextEditingController> _textControllerList = [];
  List<TextEditingController> get textControllerList => _textControllerList;

  List<MethodFields> _methodFields = [];
  List<MethodFields> get methodFields => _methodFields;

  List<FocusNode> _focusList = [];
  List<FocusNode> get focusList => _focusList;

  List<WidthDrawMethodModel>? _widthDrawMethods;
  List<WidthDrawMethodModel>? get widthDrawMethods => _widthDrawMethods;

  disburse.DisbursementMethodBody? _disbursementMethodBody;
  disburse.DisbursementMethodBody? get disbursementMethodBody => _disbursementMethodBody;

  int? _index = -1;
  int? get index =>_index;

  report.DisbursementReportModel? _disbursementReportModel;
  report.DisbursementReportModel? get disbursementReportModel => _disbursementReportModel;

  disburse.Methods? _selectedWithdrawMethod;
  disburse.Methods? get selectedWithdrawMethod => _selectedWithdrawMethod;

  void setMethodId(int? id, {bool canUpdate = true}) {
    _selectedMethodIndex = id;
    if(canUpdate){
      update();
    }
  }

  Future<void> setMethod({bool isUpdate = true}) async {
    _methodList = [];
    _textControllerList = [];
    _methodFields = [];
    _focusList = [];

    if(_widthDrawMethods == null) {
      _widthDrawMethods = await getWithdrawMethodList();
    } else {
      _widthDrawMethods = widthDrawMethods;
    }
    if(_widthDrawMethods != null && _widthDrawMethods!.isNotEmpty){
      for(int i=0; i < _widthDrawMethods!.length; i++){
        _methodList.add(DropdownItem<int>(value: i, child: SizedBox(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text('${_widthDrawMethods![i].methodName}'),
          ),
        )));
      }
      _textControllerList = [];
      _methodFields = [];
      for (var field in _widthDrawMethods![_selectedMethodIndex!].methodFields!) {
        _methodFields.add(field);
        _textControllerList.add(TextEditingController());
        _focusList.add(FocusNode());
      }
    }
    if(isUpdate) {
      update();
    }
  }

  void setMethodForEdit(disburse.Methods method) {
    _selectedWithdrawMethod = method;

    if (_widthDrawMethods != null && _widthDrawMethods!.isNotEmpty) {
      int methodIndex = _widthDrawMethods!.indexWhere((element) => element.id == method.withdrawalMethodId);

      if (methodIndex != -1) {
        _selectedMethodIndex = methodIndex;
        setMethodId(methodIndex, canUpdate: false);
        setMethod(isUpdate: false);

        if (method.methodFields != null && method.methodFields!.isNotEmpty) {
          for (int i = 0; i < method.methodFields!.length; i++) {
            if (i < _textControllerList.length) {
              _textControllerList[i].text = method.methodFields![i].userData ?? '';
            }
          }
        }
      }
    }
  }

  Future<void> addWithdrawMethod(Map<String?, String> data, {bool isUpdate = false}) async {
    _isLoading = true;
    update();
    bool isSuccess = await disbursementServiceInterface.addWithdraw(data);
    if(isSuccess) {
      Get.back();
      getDisbursementMethodList();
      showCustomSnackBar(isUpdate ? 'update_successfully'.tr : 'add_successfully'.tr, isError: false);
    }
    _isLoading = false;
    update();
  }

  Future<bool> getDisbursementMethodList() async {
    bool success = false;
    disburse.DisbursementMethodBody? disbursementMethodBody = await disbursementServiceInterface.getDisbursementMethodList();
    if(disbursementMethodBody != null) {
      success = true;
      _disbursementMethodBody = disbursementMethodBody;
    }
    update();
    return success;
  }

  Future<void> makeDefaultMethod(Map<String, String> data, int index) async {
    try {
      _index = index;
      _isLoading = true;
      update();

      bool isSuccess = await disbursementServiceInterface.makeDefaultMethod(data);

      if (isSuccess) {
        await getDisbursementMethodList();
        if (Get.isDialogOpen ?? false) {
          Get.back();
        }
        showCustomSnackBar('set_default_method_successful'.tr, isError: false);
      }
    } catch (e) {
      debugPrint('makeDefaultMethod error: $e');
    } finally {
      _isLoading = false;
      _index = -1;
      update();
    }
  }


  Future<void> deleteMethod(int id) async {
    _isDeleteLoading = true;
    update();
    bool isSuccess = await disbursementServiceInterface.deleteMethod(id);
    if(isSuccess) {
      await getDisbursementMethodList();
      if (Get.isDialogOpen ?? false) {
        Get.back();
      }
      showCustomSnackBar('method_delete_successfully'.tr, isError: false);
    }
    _isDeleteLoading = false;
    update();
  }

  Future<void> getDisbursementReport(int offset) async {
    report.DisbursementReportModel? disbursementReportModel = await disbursementServiceInterface.getDisbursementReport(offset);
    if(disbursementReportModel != null) {
      _disbursementReportModel = disbursementReportModel;
    }
    update();
  }

  Future<List<WidthDrawMethodModel>?> getWithdrawMethodList() async {
    List<WidthDrawMethodModel>? widthDrawMethods = await disbursementServiceInterface.getWithdrawMethodList();
    if(widthDrawMethods != null) {
      _widthDrawMethods = [];
      _widthDrawMethods!.addAll(widthDrawMethods);
    }
    update();
    return _widthDrawMethods;
  }

  void updateSelectedWithdrawMethod({disburse.Methods? newValue, bool shouldUpdate = true}){
    _selectedWithdrawMethod = newValue;

    if(shouldUpdate){
      update();
    }
  }

  Future<bool> createWithdrawRequest(Map<String?, dynamic> data) async {
    _isLoading = true;
    update();
    bool isSuccess = await disbursementServiceInterface.createWithdrawRequest(data);
    if(isSuccess) {
      Get.back();
      Get.find<ProfileController>().getProfile();
      getDisbursementMethodList();
      showCustomSnackBar('add_successfully'.tr, isError: false);
    }
    _isLoading = false;
    update();
    return isSuccess;
  }
  
}