import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:on_field_work/controller/finance/add_payment_request_controller.dart';
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.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/expense/expense_form_widgets.dart';
import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart';
import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart';
import 'package:on_field_work/model/employees/employee_model.dart';

Future<T?> showPaymentRequestBottomSheet<T>({
  bool isEdit = false,
  Map<String, dynamic>? existingData,
  VoidCallback? onUpdated,
}) {
  return Get.bottomSheet<T>(
    _PaymentRequestBottomSheet(
      isEdit: isEdit,
      existingData: existingData,
      onUpdated: onUpdated,
    ),
    isScrollControlled: true,
  );
}

class _PaymentRequestBottomSheet extends StatefulWidget {
  final bool isEdit;
  final Map<String, dynamic>? existingData;
  final VoidCallback? onUpdated;

  const _PaymentRequestBottomSheet({
    this.isEdit = false,
    this.existingData,
    this.onUpdated,
  });

  @override
  State<_PaymentRequestBottomSheet> createState() =>
      _PaymentRequestBottomSheetState();
}

class _PaymentRequestBottomSheetState extends State<_PaymentRequestBottomSheet>
    with UIMixin {
  final controller = Get.put(AddPaymentRequestController());
  final _formKey = GlobalKey<FormState>();

  final _projectDropdownKey = GlobalKey();
  final _categoryDropdownKey = GlobalKey();
  final _currencyDropdownKey = GlobalKey();

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

    WidgetsBinding.instance.addPostFrameCallback((_) async {
      if (widget.isEdit && widget.existingData != null) {
        final data = widget.existingData!;

        controller.titleController.text = data["title"] ?? "";
        controller.amountController.text = data["amount"]?.toString() ?? "";
        controller.descriptionController.text = data["description"] ?? "";

        if (data["dueDate"] != null && data["dueDate"].toString().isNotEmpty) {
          DateTime? dueDate = DateTime.tryParse(data["dueDate"].toString());
          if (dueDate != null) {
            controller.selectedDueDate.value = dueDate;
            controller.dueDateController.text =
                DateFormat('dd MMM yyyy').format(dueDate);
          }
        }

        controller.selectedProject.value = {
          'id': data["projectId"],
          'name': data["projectName"],
        };

        controller.selectedPayee.value = data["payee"] ?? "";
        controller.isAdvancePayment.value = data["isAdvancePayment"] ?? false;

        // When categories and currencies load, set selected ones
        everAll([controller.categories, controller.currencies], (_) {
          controller.selectedCategory.value = controller.categories
              .firstWhereOrNull((c) => c.id == data["expenseCategoryId"]);
          controller.selectedCurrency.value = controller.currencies
              .firstWhereOrNull((c) => c.id == data["currencyId"]);
        });

        final attachmentsData = data["attachments"];
        if (attachmentsData != null &&
            attachmentsData is List &&
            attachmentsData.isNotEmpty) {
          final attachments = attachmentsData
              .whereType<Map<String, dynamic>>()
              .map((a) => {
                    "id": a["documentId"] ?? a["id"],
                    "fileName": a["fileName"],
                    "url": a["url"],
                    "thumbUrl": a["thumbUrl"],
                    "fileSize": a["fileSize"] ?? 0,
                    "contentType": a["contentType"] ?? "",
                    "isActive": true,
                  })
              .toList();
          controller.existingAttachments.assignAll(attachments);
        } else {
          controller.existingAttachments.clear();
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Obx(
      () => SafeArea(
        child: Form(
          key: _formKey,
          child: BaseBottomSheet(
            title: widget.isEdit ? "Edit Payment Request" : "Create Payment Request",
            isSubmitting: controller.isSubmitting.value,
            onCancel: Get.back,
            submitText: "Save as Draft",
            onSubmit: () async {
              if (_formKey.currentState!.validate() && _validateSelections()) {
                bool success = false;

                if (widget.isEdit && widget.existingData != null) {
                  final requestId = widget.existingData!['id']?.toString() ?? '';
                  if (requestId.isNotEmpty) {
                    success = await controller.submitEditedPaymentRequest(
                        requestId: requestId);
                  } else {
                    _showError("Invalid Payment Request ID");
                    return;
                  }
                } else {
                  success = await controller.submitPaymentRequest();
                }

                if (success) {
                  Get.back();
                  widget.onUpdated?.call();

                  showAppSnackbar(
                    title: "Success",
                    message: widget.isEdit
                        ? "Payment request updated successfully!"
                        : "Payment request created successfully!",
                    type: SnackbarType.success,
                  );
                }
              }
            },
            child: SingleChildScrollView(
              padding: const EdgeInsets.only(bottom: 20),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  _buildDropdown(
                    "Select Project",
                    Icons.work_outline,
                    controller.selectedProject.value?['name'] ?? "Select Project",
                    controller.globalProjects,
                    (p) => p['name'],
                    controller.selectProject,
                    key: _projectDropdownKey,
                  ),
                  _gap(),
                  _buildDropdown(
                    "Expense Category",
                    Icons.category_outlined,
                    controller.selectedCategory.value?.name ?? "Select Category",
                    controller.categories,
                    (c) => c.name,
                    controller.selectCategory,
                    key: _categoryDropdownKey,
                  ),
                  _gap(),
                  _buildTextField("Title", Icons.title_outlined,
                      controller.titleController,
                      hint: "Enter title", validator: Validators.requiredField),
                  _gap(),
                  _buildRadio("Is Advance Payment", Icons.attach_money_outlined,
                      controller.isAdvancePayment, ["Yes", "No"]),
                  _gap(),
                  _buildDueDateField(),
                  _gap(),
                  _buildTextField("Amount", Icons.currency_rupee,
                      controller.amountController,
                      hint: "Enter Amount",
                      keyboardType: TextInputType.number,
                      validator: (v) => (v != null &&
                              v.isNotEmpty &&
                              double.tryParse(v) != null)
                          ? null
                          : "Enter valid amount"),
                  _gap(),
                  _buildPayeeField(),
                  _gap(),
                  _buildDropdown(
                    "Currency",
                    Icons.monetization_on_outlined,
                    controller.selectedCurrency.value?.currencyName ?? "Select Currency",
                    controller.currencies,
                    (c) => c.currencyName,
                    controller.selectCurrency,
                    key: _currencyDropdownKey,
                  ),
                  _gap(),
                  _buildTextField("Description", Icons.description_outlined,
                      controller.descriptionController,
                      hint: "Enter description",
                      maxLines: 3,
                      validator: Validators.requiredField),
                  _gap(),
                  _buildAttachmentsSection(),
                  MySpacing.height(30),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildDropdown<T>(String title, IconData icon, String value,
      List<T> options, String Function(T) getLabel, ValueChanged<T> onSelected,
      {required GlobalKey key}) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SectionTitle(icon: icon, title: title, requiredField: true),
        MySpacing.height(6),
        DropdownTile(
          key: key,
          title: value,
          onTap: () => _showOptionList(options, getLabel, onSelected, key),
        ),
      ],
    );
  }

  Widget _buildTextField(
      String title, IconData icon, 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 _buildRadio(
      String title, IconData icon, RxBool controllerBool, List<String> labels) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Icon(icon, size: 20),
            const SizedBox(width: 6),
            Text(title,
                style:
                    const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)),
          ],
        ),
        MySpacing.height(6),
        Obx(() => Row(
              children: labels.asMap().entries.map((entry) {
                final i = entry.key;
                final label = entry.value;
                final value = i == 0;

                return Expanded(
                  child: RadioListTile<bool>(
                    contentPadding: EdgeInsets.zero,
                    title: Text(label),
                    value: value,
                    groupValue: controllerBool.value,
                    activeColor: contentTheme.primary,
                    onChanged: (val) =>
                        val != null ? controllerBool.value = val : null,
                  ),
                );
              }).toList(),
            )),
      ],
    );
  }

  Widget _buildDueDateField() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SectionTitle(
            icon: Icons.calendar_today, title: "Due To Date", requiredField: true),
        MySpacing.height(6),
        GestureDetector(
          onTap: () => controller.pickDueDate(context),
          child: AbsorbPointer(
            child: TextFormField(
              controller: controller.dueDateController,
              decoration: InputDecoration(
                hintText: "Select Due Date",
                filled: true,
                fillColor: Colors.grey.shade100,
                contentPadding:
                    const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(8),
                  borderSide: BorderSide(color: Colors.grey.shade300),
                ),
              ),
              validator: (_) => controller.selectedDueDate.value == null
                  ? "Please select a due date"
                  : null,
            ),
          ),
        ),
      ],
    );
  }

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

  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,
          );
        }),
      ],
    );
  }

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

  Future<void> _showOptionList<T>(List<T> options, String Function(T) getLabel,
      ValueChanged<T> onSelected, GlobalKey key) async {
    if (options.isEmpty) {
      _showError("No options available");
      return;
    }

    if (key.currentContext == null) {
      final selected = await showDialog<T>(
        context: context,
        builder: (_) => SimpleDialog(
          children: options
              .map((opt) => SimpleDialogOption(
                    onPressed: () => Navigator.pop(context, opt),
                    child: Text(getLabel(opt)),
                  ))
              .toList(),
        ),
      );
      if (selected != null) onSelected(selected);
      return;
    }

    final RenderBox button = key.currentContext!.findRenderObject() as RenderBox;
    final RenderBox overlay =
        Overlay.of(context).context.findRenderObject() as RenderBox;
    final position = button.localToGlobal(Offset.zero, ancestor: overlay);

    final selected = await showMenu<T>(
      context: context,
      position: RelativeRect.fromLTRB(
          position.dx,
          position.dy + button.size.height,
          overlay.size.width - position.dx - button.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 == null ||
        controller.selectedProject.value!['id'].toString().isEmpty) {
      return _showError("Please select a project");
    }
    if (controller.selectedCategory.value == null) {
      return _showError("Please select a category");
    }
    if (controller.selectedPayee.value == null) {
      return _showError("Please select a payee");
    }
    if (controller.selectedCurrency.value == null) {
      return _showError("Please select currency");
    }
    return true;
  }

  Future<void> _showPayeeSelector() async {
    final result = await showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (_) => EmployeeSelectionBottomSheet(
        title: "Select Payee",
        multipleSelection: false,
        initiallySelected: controller.selectedPayee.value != null
            ? [controller.selectedPayee.value!]
            : [],
      ),
    );

    if (result is EmployeeModel) {
      controller.selectedPayee.value = result;
    }
  }

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