/// UPDATED — SafeArea + proper bottom padding added
/// No other functionality modified.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'package:on_field_work/controller/expense/add_expense_controller.dart';
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart';
import 'package:on_field_work/model/expense/expense_type_model.dart';
import 'package:on_field_work/model/expense/payment_types_model.dart';
import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart';
import 'package:on_field_work/helpers/utils/validators.dart';
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart';
import 'package:on_field_work/helpers/widgets/expense/expense_form_widgets.dart';
import 'package:on_field_work/model/employees/employee_model.dart';
import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart';

Future<T?> showAddExpenseBottomSheet<T>({
  bool isEdit = false,
  Map<String, dynamic>? existingExpense,
}) {
  return Get.bottomSheet<T>(
    _AddExpenseBottomSheet(
      isEdit: isEdit,
      existingExpense: existingExpense,
    ),
    isScrollControlled: true,
  );
}

class _AddExpenseBottomSheet extends StatefulWidget {
  final bool isEdit;
  final Map<String, dynamic>? existingExpense;

  const _AddExpenseBottomSheet({
    this.isEdit = false,
    this.existingExpense,
  });

  @override
  State<_AddExpenseBottomSheet> createState() => _AddExpenseBottomSheetState();
}

class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet>
    with UIMixin {
  final AddExpenseController controller = Get.put(AddExpenseController());
  final _formKey = GlobalKey<FormState>();

  final GlobalKey _projectDropdownKey = GlobalKey();
  final GlobalKey _expenseTypeDropdownKey = GlobalKey();
  final GlobalKey _paymentModeDropdownKey = GlobalKey();

  Future<void> _showEmployeeList() async {
    final result = await showModalBottomSheet<dynamic>(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
      ),
      builder: (_) => EmployeeSelectionBottomSheet(
        initiallySelected: controller.selectedPaidBy.value != null
            ? [controller.selectedPaidBy.value!]
            : [],
        multipleSelection: false,
        title: "Select Paid By",
      ),
    );

    if (result == null) return;

    if (result is EmployeeModel) {
      controller.setSelectedPaidBy(result);
    } else if (result is List && result.isNotEmpty) {
      controller.setSelectedPaidBy(result.first as EmployeeModel);
    }

    try {
      controller.employeeSearchController.clear();
      controller.employeeSearchResults.clear();
    } catch (_) {}
  }

  Future<void> _showOptionList<T>(
    List<T> options,
    String Function(T) getLabel,
    ValueChanged<T> onSelected,
    GlobalKey triggerKey,
  ) async {
    final RenderBox btn =
        triggerKey.currentContext!.findRenderObject() as RenderBox;
    final RenderBox overlay =
        Overlay.of(context).context.findRenderObject() as RenderBox;
    final pos = btn.localToGlobal(Offset.zero, ancestor: overlay);

    final selected = await showMenu<T>(
      context: context,
      position: RelativeRect.fromLTRB(
        pos.dx,
        pos.dy + btn.size.height,
        overlay.size.width - pos.dx - btn.size.width,
        0,
      ),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      items: options
          .map((opt) => PopupMenuItem<T>(
                value: opt,
                child: Text(getLabel(opt)),
              ))
          .toList(),
    );

    if (selected != null) onSelected(selected);
  }

  bool _validateSelections() {
    if (controller.selectedProject.value.isEmpty) {
      _showError("Please select a project");
      return false;
    }
    if (controller.selectedExpenseType.value == null) {
      _showError("Please select an Expense Category");
      return false;
    }
    if (controller.selectedPaymentMode.value == null) {
      _showError("Please select a payment mode");
      return false;
    }
    if (controller.selectedPaidBy.value == null) {
      _showError("Please select a person who paid");
      return false;
    }
    if (controller.attachments.isEmpty &&
        controller.existingAttachments.isEmpty) {
      _showError("Please attach at least one document");
      return false;
    }
    return true;
  }

  void _showError(String msg) {
    showAppSnackbar(
      title: "Error",
      message: msg,
      type: SnackbarType.error,
    );
  }

  @override
  Widget build(BuildContext context) {
    final bottomInset = MediaQuery.of(context).viewPadding.bottom;

    return Obx(
      () => Form(
        key: _formKey,
        child: SafeArea(
          bottom: true,
          child: BaseBottomSheet(
            title: widget.isEdit ? "Edit Expense" : "Add Expense",
            isSubmitting: controller.isSubmitting.value,
            onCancel: Get.back,
            onSubmit: () {
              if (_formKey.currentState!.validate() && _validateSelections()) {
                controller.submitOrUpdateExpense();
              } else {
                _showError("Please fill all required fields correctly");
              }
            },
            child: SingleChildScrollView(
              padding: EdgeInsets.only(bottom: bottomInset + 24),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  _buildDropdownField<String>(
                    icon: Icons.work_outline,
                    title: "Project",
                    requiredField: true,
                    value: controller.selectedProject.value.isEmpty
                        ? "Select Project"
                        : controller.selectedProject.value,
                    onTap: () => _showOptionList<String>(
                      controller.globalProjects.toList(),
                      (p) => p,
                      (val) => controller.selectedProject.value = val,
                      _projectDropdownKey,
                    ),
                    dropdownKey: _projectDropdownKey,
                  ),
                  _gap(),
                  _buildDropdownField<ExpenseTypeModel>(
                    icon: Icons.category_outlined,
                    title: "Expense Category",
                    requiredField: true,
                    value: controller.selectedExpenseType.value?.name ??
                        "Select Expense Category",
                    onTap: () => _showOptionList<ExpenseTypeModel>(
                      controller.expenseTypes.toList(),
                      (e) => e.name,
                      (val) => controller.selectedExpenseType.value = val,
                      _expenseTypeDropdownKey,
                    ),
                    dropdownKey: _expenseTypeDropdownKey,
                  ),
                  if (controller
                          .selectedExpenseType.value?.noOfPersonsRequired ==
                      true) ...[
                    _gap(),
                    _buildTextFieldSection(
                      icon: Icons.people_outline,
                      title: "No. of Persons",
                      controller: controller.noOfPersonsController,
                      hint: "Enter No. of Persons",
                      keyboardType: TextInputType.number,
                      validator: Validators.requiredField,
                    ),
                  ],
                  _gap(),
                  _buildTextFieldSection(
                    icon: Icons.confirmation_number_outlined,
                    title: "GST No.",
                    controller: controller.gstController,
                    hint: "Enter GST No.",
                  ),
                  _gap(),
                  _buildDropdownField<PaymentModeModel>(
                    icon: Icons.payment,
                    title: "Payment Mode",
                    requiredField: true,
                    value: controller.selectedPaymentMode.value?.name ??
                        "Select Payment Mode",
                    onTap: () => _showOptionList<PaymentModeModel>(
                      controller.paymentModes.toList(),
                      (p) => p.name,
                      (val) => controller.selectedPaymentMode.value = val,
                      _paymentModeDropdownKey,
                    ),
                    dropdownKey: _paymentModeDropdownKey,
                  ),
                  _gap(),
                  _buildPaidBySection(),
                  _gap(),
                  _buildTextFieldSection(
                    icon: Icons.currency_rupee,
                    title: "Amount",
                    controller: controller.amountController,
                    hint: "Enter Amount",
                    keyboardType: TextInputType.number,
                    validator: (v) => Validators.isNumeric(v ?? "")
                        ? null
                        : "Enter valid amount",
                  ),
                  _gap(),
                  _buildTextFieldSection(
                    icon: Icons.store_mall_directory_outlined,
                    title: "Supplier Name/Transporter Name/Other",
                    controller: controller.supplierController,
                    hint: "Enter Supplier Name/Transporter Name or Other",
                    validator: Validators.nameValidator,
                  ),
                  _gap(),
                  _buildTextFieldSection(
                    icon: Icons.confirmation_number_outlined,
                    title: "Transaction ID",
                    controller: controller.transactionIdController,
                    hint: "Enter Transaction ID",
                    validator: (v) => (v != null && v.isNotEmpty)
                        ? Validators.transactionIdValidator(v)
                        : null,
                  ),
                  _gap(),
                  _buildTransactionDateField(),
                  _gap(),
                  _buildLocationField(),
                  _gap(),
                  _buildAttachmentsSection(),
                  _gap(),
                  _buildTextFieldSection(
                    icon: Icons.description_outlined,
                    title: "Description",
                    controller: controller.descriptionController,
                    hint: "Enter Description",
                    maxLines: 3,
                    validator: Validators.requiredField,
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _gap([double h = 16]) => MySpacing.height(h);

  Widget _buildDropdownField<T>({
    required IconData icon,
    required String title,
    required bool requiredField,
    required String value,
    required VoidCallback onTap,
    required GlobalKey dropdownKey,
  }) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SectionTitle(icon: icon, title: title, requiredField: requiredField),
        MySpacing.height(6),
        DropdownTile(key: dropdownKey, title: value, onTap: onTap),
      ],
    );
  }

  Widget _buildTextFieldSection({
    required IconData icon,
    required String title,
    required TextEditingController controller,
    String? hint,
    TextInputType? keyboardType,
    FormFieldValidator<String>? validator,
    int maxLines = 1,
  }) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SectionTitle(
            icon: icon, title: title, requiredField: validator != null),
        MySpacing.height(6),
        CustomTextField(
          controller: controller,
          hint: hint ?? "",
          keyboardType: keyboardType ?? TextInputType.text,
          validator: validator,
          maxLines: maxLines,
        ),
      ],
    );
  }

  Widget _buildPaidBySection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SectionTitle(
            icon: Icons.person_outline, title: "Paid By", requiredField: true),
        MySpacing.height(6),
        GestureDetector(
          onTap: _showEmployeeList,
          child: TileContainer(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Expanded(
                  child: Text(
                    controller.selectedPaidBy.value?.name ?? "Select Paid By",
                    style: const TextStyle(fontSize: 15),
                    overflow: TextOverflow.ellipsis,
                  ),
                ),
                const Icon(Icons.arrow_drop_down, size: 22),
              ],
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildTransactionDateField() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SectionTitle(
            icon: Icons.calendar_today,
            title: "Transaction Date",
            requiredField: true),
        MySpacing.height(6),
        GestureDetector(
          onTap: () => controller.pickTransactionDate(context),
          child: AbsorbPointer(
            child: CustomTextField(
              controller: controller.transactionDateController,
              hint: "Select Transaction Date",
              validator: Validators.requiredField,
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildLocationField() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SectionTitle(icon: Icons.location_on_outlined, title: "Location"),
        MySpacing.height(6),
        TextFormField(
          controller: controller.locationController,
          decoration: InputDecoration(
            hintText: "Enter Location",
            filled: true,
            fillColor: Colors.grey.shade100,
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(8),
            ),
            contentPadding:
                const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
            suffixIcon: controller.isFetchingLocation.value
                ? const Padding(
                    padding: EdgeInsets.all(12),
                    child: SizedBox(
                      width: 18,
                      height: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    ),
                  )
                : IconButton(
                    icon: const Icon(Icons.my_location),
                    onPressed: controller.fetchCurrentLocation,
                  ),
          ),
        ),
      ],
    );
  }

  Widget _buildAttachmentsSection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SectionTitle(
          icon: Icons.attach_file,
          title: "Attachments",
          requiredField: true,
        ),
        MySpacing.height(10),
        Obx(() {
          if (controller.isProcessingAttachment.value) {
            return Center(
              child: Column(
                children: [
                  CircularProgressIndicator(
                    color: contentTheme.primary,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    "Processing image, please wait...",
                    style: TextStyle(
                      fontSize: 14,
                      color: contentTheme.primary,
                    ),
                  ),
                ],
              ),
            );
          }

          return AttachmentsSection(
            attachments: controller.attachments,
            existingAttachments: controller.existingAttachments,
            onRemoveNew: controller.removeAttachment,
            controller: controller,
            onRemoveExisting: (item) async {
              await showDialog(
                context: context,
                barrierDismissible: false,
                builder: (_) => ConfirmDialog(
                  title: "Remove Attachment",
                  message: "Are you sure you want to remove this attachment?",
                  confirmText: "Remove",
                  icon: Icons.delete,
                  confirmColor: Colors.redAccent,
                  onConfirm: () async {
                    final index = controller.existingAttachments.indexOf(item);
                    if (index != -1) {
                      controller.existingAttachments[index]['isActive'] = false;
                      controller.existingAttachments.refresh();
                    }
                    showAppSnackbar(
                      title: 'Removed',
                      message: 'Attachment has been removed.',
                      type: SnackbarType.success,
                    );
                  },
                ),
              );
            },
            onAdd: controller.pickAttachments,
          );
        }),
      ],
    );
  }
}
