import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:on_field_work/controller/finance/payment_request_controller.dart';
import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart';
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
import 'package:on_field_work/helpers/widgets/my_text.dart';
import 'package:on_field_work/helpers/widgets/my_text_style.dart';
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart';
import 'package:on_field_work/helpers/widgets/date_range_picker.dart';
import 'package:on_field_work/model/employees/employee_model.dart';
import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart';

class PaymentRequestFilterBottomSheet extends StatefulWidget {
  final PaymentRequestController controller;
  final ScrollController scrollController;

  const PaymentRequestFilterBottomSheet({
    super.key,
    required this.controller,
    required this.scrollController,
  });

  @override
  State<PaymentRequestFilterBottomSheet> createState() =>
      _PaymentRequestFilterBottomSheetState();
}

class _PaymentRequestFilterBottomSheetState
    extends State<PaymentRequestFilterBottomSheet> with UIMixin {
  final Rx<DateTime?> startDate = Rx<DateTime?>(null);
  final Rx<DateTime?> endDate = Rx<DateTime?>(null);

  final RxString selectedProjectId = ''.obs;
  final RxList<EmployeeModel> selectedSubmittedBy = <EmployeeModel>[].obs;
  final RxList<EmployeeModel> selectedPayees = <EmployeeModel>[].obs;
  final RxString selectedCategoryId = ''.obs;
  final RxString selectedCurrencyId = ''.obs;
  final RxString selectedStatusId = ''.obs;

  String get selectedProjectName =>
      widget.controller.projects
          .firstWhereOrNull((e) => e.id == selectedProjectId.value)
          ?.name ??
      'Please select...';

  String get selectedCategoryName =>
      widget.controller.categories
          .firstWhereOrNull((e) => e.id == selectedCategoryId.value)
          ?.name ??
      'Please select...';

  String get selectedCurrencyName =>
      widget.controller.currencies
          .firstWhereOrNull((e) => e.id == selectedCurrencyId.value)
          ?.name ??
      'Please select...';

  String get selectedStatusName =>
      widget.controller.statuses
          .firstWhereOrNull((e) => e.id == selectedStatusId.value)
          ?.name ??
      'Please select...';

  final RxBool isFilterLoading = true.obs;

  final RxList<String> projectNames = <String>[].obs;
  final RxList<String> submittedByNames = <String>[].obs;
  final RxList<String> payeeNames = <String>[].obs;
  final RxList<String> categoryNames = <String>[].obs;
  final RxList<String> currencyNames = <String>[].obs;
  final RxList<String> statusNames = <String>[].obs;

  @override
  void initState() {
    super.initState();
    _loadFilterData();
  }

  Future<void> _loadFilterData() async {
    isFilterLoading.value = true;
    await widget.controller.fetchPaymentRequestFilterOptions();

    projectNames.assignAll(widget.controller.projects.map((e) => e.name));
    submittedByNames.assignAll(widget.controller.createdBy.map((e) => e.name));
    payeeNames.assignAll(widget.controller.payees.map((e) => e.name));
    categoryNames.assignAll(widget.controller.categories.map((e) => e.name));
    currencyNames.assignAll(widget.controller.currencies.map((e) => e.name));
    statusNames.assignAll(widget.controller.statuses.map((e) => e.name));

    final existing = widget.controller.appliedFilter;

    if (existing.isNotEmpty) {
      if (existing['projectIds'] != null &&
          (existing['projectIds'] as List).isNotEmpty) {
        selectedProjectId.value = (existing['projectIds'] as List).first;
      }

      if (existing['createdByIds'] != null &&
          existing['createdByIds'] is List) {
        selectedSubmittedBy.assignAll(
          (existing['createdByIds'] as List)
              .map((id) => widget.controller.createdBy
                  .firstWhereOrNull((e) => e.id == id))
              .whereType<EmployeeModel>()
              .toList(),
        );
      }

      if (existing['payees'] != null && existing['payees'] is List) {
        selectedPayees.assignAll(
          (existing['payees'] as List)
              .map((id) =>
                  widget.controller.payees.firstWhereOrNull((e) => e.id == id))
              .whereType<EmployeeModel>()
              .toList(),
        );
      }

      if (existing['expenseCategoryIds'] != null &&
          (existing['expenseCategoryIds'] as List).isNotEmpty) {
        selectedCategoryId.value =
            (existing['expenseCategoryIds'] as List).first;
      }

      if (existing['currencyIds'] != null &&
          (existing['currencyIds'] as List).isNotEmpty) {
        selectedCurrencyId.value = (existing['currencyIds'] as List).first;
      }

      if (existing['statusIds'] != null &&
          (existing['statusIds'] as List).isNotEmpty) {
        selectedStatusId.value = (existing['statusIds'] as List).first;
      }

      if (existing['startDate'] != null && existing['endDate'] != null) {
        startDate.value = DateTime.tryParse(existing['startDate']);
        endDate.value = DateTime.tryParse(existing['endDate']);
      }
    }

    isFilterLoading.value = false;
  }

  Future<List<EmployeeModel>> searchEmployees(
      String query, List<String> items) async {
    final allEmployees = items
        .map((e) => EmployeeModel(
              id: e,
              name: e,
              firstName: e,
              lastName: '',
              jobRoleID: '',
              employeeId: e,
              designation: '',
              activity: 0,
              action: 0,
              jobRole: '',
              email: '-',
              phoneNumber: '-',
            ))
        .toList();

    if (query.trim().isEmpty) return allEmployees;

    return allEmployees
        .where((e) => e.name.toLowerCase().contains(query.toLowerCase()))
        .toList();
  }

  @override
  Widget build(BuildContext context) {
    return BaseBottomSheet(
      title: 'Filter Payment Requests',
      onCancel: () => Get.back(),
      onSubmit: () {
        _applyFilters();
        Get.back();
      },
      submitText: 'Apply',
      submitColor: contentTheme.primary,
      submitIcon: Icons.check_circle_outline,

      /// ⭐⭐⭐ IMPORTANT FIX ⭐⭐⭐
      /// Prevents bottom part from hiding under 3-button nav bar in landscape
      child: SafeArea(
        minimum: const EdgeInsets.only(bottom: 20),
        child: SingleChildScrollView(
          controller: widget.scrollController,
          padding: const EdgeInsets.only(bottom: 40), // extra bottom spacing
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Align(
                alignment: Alignment.centerRight,
                child: TextButton(
                  onPressed: clearFilters,
                  child: MyText(
                    "Reset Filters",
                    style: MyTextStyle.labelMedium(
                      color: Colors.red,
                      fontWeight: 600,
                    ),
                  ),
                ),
              ),
              MySpacing.height(8),
              _buildDateRangeFilter(),
              MySpacing.height(16),
              _buildProjectFilter(),
              MySpacing.height(16),
              _buildSubmittedByFilter(),
              MySpacing.height(16),
              _buildPayeeFilter(),
              MySpacing.height(16),
              _buildCategoryFilter(),
              MySpacing.height(16),
              _buildCurrencyFilter(),
              MySpacing.height(16),
              _buildStatusFilter(),
            ],
          ),
        ),
      ),
    );
  }

  void clearFilters() {
    startDate.value = null;
    endDate.value = null;
    selectedProjectId.value = '';
    selectedSubmittedBy.clear();
    selectedPayees.clear();
    selectedCategoryId.value = '';
    selectedCurrencyId.value = '';
    selectedStatusId.value = '';
    widget.controller.setFilterApplied(false);
  }

  void _applyFilters() {
    final Map<String, dynamic> filter = {
      "projectIds":
          selectedProjectId.value.isEmpty ? [] : [selectedProjectId.value],
      "createdByIds": selectedSubmittedBy.map((e) => e.id).toList(),
      "payees": selectedPayees.map((e) => e.id).toList(),
      "expenseCategoryIds":
          selectedCategoryId.value.isEmpty ? [] : [selectedCategoryId.value],
      "currencyIds":
          selectedCurrencyId.value.isEmpty ? [] : [selectedCurrencyId.value],
      "statusIds":
          selectedStatusId.value.isEmpty ? [] : [selectedStatusId.value],
      "startDate": startDate.value?.toIso8601String(),
      "endDate": endDate.value?.toIso8601String(),
    };

    widget.controller.applyFilter(filter);
  }

  Widget _buildField(String label, Widget child) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        MyText.labelMedium(label),
        MySpacing.height(8),
        child,
      ],
    );
  }

  Widget _buildDateRangeFilter() {
    return _buildField(
      "Filter By Date",
      DateRangePickerWidget(
        startDate: startDate,
        endDate: endDate,
        startLabel: "Start Date",
        endLabel: "End Date",
        onDateRangeSelected: (start, end) {
          startDate.value = start;
          endDate.value = end;
        },
      ),
    );
  }

  Widget _buildProjectFilter() {
    return _buildField(
      "Project",
      Obx(() {
        if (isFilterLoading.value) return const CircularProgressIndicator();
        return _popupSelector(
          currentValue: selectedProjectName,
          items: projectNames,
          onSelected: (value) {
            final proj = widget.controller.projects
                .firstWhereOrNull((e) => e.name == value);
            if (proj != null) selectedProjectId.value = proj.id;
          },
        );
      }),
    );
  }

  Widget _buildSubmittedByFilter() {
    return _buildField(
      "Submitted By",
      Obx(() {
        if (isFilterLoading.value) return const CircularProgressIndicator();
        return _employeeSelector(
            selectedSubmittedBy, "Search Submitted By", submittedByNames);
      }),
    );
  }

  Widget _buildPayeeFilter() {
    return _buildField(
      "Payee",
      Obx(() {
        if (isFilterLoading.value) return const CircularProgressIndicator();
        return _employeeSelector(selectedPayees, "Search Payee", payeeNames);
      }),
    );
  }

  Widget _buildCategoryFilter() {
    return _buildField(
      "Category",
      Obx(() {
        if (isFilterLoading.value) return const CircularProgressIndicator();
        return _popupSelector(
          currentValue: selectedCategoryName,
          items: categoryNames,
          onSelected: (value) {
            final cat = widget.controller.categories
                .firstWhereOrNull((e) => e.name == value);
            if (cat != null) selectedCategoryId.value = cat.id;
          },
        );
      }),
    );
  }

  Widget _buildCurrencyFilter() {
    return _buildField(
      "Currency",
      Obx(() {
        if (isFilterLoading.value) return const CircularProgressIndicator();
        return _popupSelector(
          currentValue: selectedCurrencyName,
          items: currencyNames,
          onSelected: (value) {
            final cur = widget.controller.currencies
                .firstWhereOrNull((e) => e.name == value);
            if (cur != null) selectedCurrencyId.value = cur.id;
          },
        );
      }),
    );
  }

  Widget _buildStatusFilter() {
    return _buildField(
      "Status",
      Obx(() {
        if (isFilterLoading.value) return const CircularProgressIndicator();
        return _popupSelector(
          currentValue: selectedStatusName,
          items: statusNames,
          onSelected: (value) {
            final st = widget.controller.statuses
                .firstWhereOrNull((e) => e.name == value);
            if (st != null) selectedStatusId.value = st.id;
          },
        );
      }),
    );
  }

  Widget _popupSelector({
    required String currentValue,
    required List<String> items,
    required ValueChanged<String> onSelected,
  }) {
    return PopupMenuButton<String>(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      onSelected: onSelected,
      itemBuilder: (context) =>
          items.map((e) => PopupMenuItem(value: e, child: MyText(e))).toList(),
      child: Container(
        padding: MySpacing.all(12),
        decoration: BoxDecoration(
          color: Colors.grey.shade100,
          border: Border.all(color: Colors.grey.shade300),
          borderRadius: BorderRadius.circular(12),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Expanded(
              child: MyText(
                currentValue,
                style: const TextStyle(color: Colors.black87),
                overflow: TextOverflow.ellipsis,
              ),
            ),
            const Icon(Icons.arrow_drop_down, color: Colors.grey),
          ],
        ),
      ),
    );
  }

  Widget _employeeSelector(RxList<EmployeeModel> selectedEmployees,
      String title, List<String> items) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Obx(() {
          if (selectedEmployees.isEmpty) return const SizedBox.shrink();
          return Wrap(
            spacing: 8,
            children: selectedEmployees
                .map((emp) => Chip(
                      label: MyText(emp.name),
                      onDeleted: () => selectedEmployees.remove(emp),
                    ))
                .toList(),
          );
        }),
        MySpacing.height(8),
        GestureDetector(
          onTap: () async {
            final result = await showModalBottomSheet<List<EmployeeModel>>(
              context: context,
              isScrollControlled: true,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
              ),
              builder: (context) => EmployeeSelectionBottomSheet(
                initiallySelected: selectedEmployees.toList(),
                multipleSelection: true,
                title: title,
              ),
            );
            if (result != null) selectedEmployees.assignAll(result);
          },
          child: Container(
            padding: MySpacing.all(12),
            decoration: BoxDecoration(
              color: Colors.grey.shade100,
              borderRadius: BorderRadius.circular(12),
              border: Border.all(color: Colors.grey.shade300),
            ),
            child: Row(
              children: [
                const Icon(Icons.search, color: Colors.grey),
                MySpacing.width(8),
                Expanded(child: MyText(title)),
              ],
            ),
          ),
        ),
      ],
    );
  }
}
