import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:collection/collection.dart';
import 'package:on_field_work/controller/directory/add_contact_controller.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/model/directory/contact_model.dart';
import 'package:on_field_work/helpers/utils/contact_picker_helper.dart';
import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart';

class AddContactBottomSheet extends StatefulWidget {
  final ContactModel? existingContact;
  const AddContactBottomSheet({super.key, this.existingContact});

  @override
  State<AddContactBottomSheet> createState() => _AddContactBottomSheetState();
}

class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
  final controller = Get.put(AddContactController());
  final formKey = GlobalKey<FormState>();

  final nameCtrl = TextEditingController();
  final orgCtrl = TextEditingController();
  final designationCtrl = TextEditingController();
  final addrCtrl = TextEditingController();
  final descCtrl = TextEditingController();
  final tagCtrl = TextEditingController();

  final showAdvanced = false.obs;
  final bucketError = ''.obs;

  final emailCtrls = <TextEditingController>[].obs;
  final emailLabels = <RxString>[].obs;

  final phoneCtrls = <TextEditingController>[].obs;
  final phoneLabels = <RxString>[].obs;

  @override
  void initState() {
    super.initState();
    controller.resetForm();
    _initFields();
  }

  void _initFields() {
    final c = widget.existingContact;
    if (c != null) {
      nameCtrl.text = c.name;
      orgCtrl.text = c.organization;
      designationCtrl.text = c.designation ?? '';
      addrCtrl.text = c.address;
      descCtrl.text = c.description;

      emailCtrls.assignAll(c.contactEmails.isEmpty
          ? [TextEditingController()]
          : c.contactEmails
              .map((e) => TextEditingController(text: e.emailAddress)));
      emailLabels.assignAll(c.contactEmails.isEmpty
          ? ['Office'.obs]
          : c.contactEmails.map((e) => e.label.obs));

      phoneCtrls.assignAll(c.contactPhones.isEmpty
          ? [TextEditingController()]
          : c.contactPhones
              .map((p) => TextEditingController(text: p.phoneNumber)));
      phoneLabels.assignAll(c.contactPhones.isEmpty
          ? ['Work'.obs]
          : c.contactPhones.map((p) => p.label.obs));

      controller.enteredTags.assignAll(c.tags.map((e) => e.name));

      ever(controller.isInitialized, (bool ready) {
        if (ready) {
          // Buckets - map all
          if (c.bucketIds.isNotEmpty) {
            final names = c.bucketIds
                .map((id) {
                  return controller.bucketsMap.entries
                      .firstWhereOrNull((e) => e.value == id)
                      ?.key;
                })
                .whereType<String>()
                .toList();
            controller.selectedBuckets.assignAll(names);
          }
          // Projects and Category mapping - as before
          final projectIds = c.projectIds;
          if (projectIds != null) {
            controller.selectedProjects.assignAll(
              projectIds
                  .map((id) => controller.projectsMap.entries
                      .firstWhereOrNull((e) => e.value == id)
                      ?.key)
                  .whereType<String>()
                  .toList(),
            );
          }
          final category = c.contactCategory?.name;
          if (category != null) controller.selectedCategory.value = category;
        }
      });
    } else {
      showAdvanced.value = false; // Optional
      emailCtrls.add(TextEditingController());
      emailLabels.add('Office'.obs);
      phoneCtrls.add(TextEditingController());
      phoneLabels.add('Work'.obs);
    }
  }

  @override
  void dispose() {
    nameCtrl.dispose();
    orgCtrl.dispose();
    designationCtrl.dispose();
    addrCtrl.dispose();
    descCtrl.dispose();
    tagCtrl.dispose();
    emailCtrls.forEach((c) => c.dispose());
    phoneCtrls.forEach((c) => c.dispose());
    Get.delete<AddContactController>();
    super.dispose();
  }

  Widget _labelWithStar(String label, {bool required = false}) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        MyText.labelMedium(label),
        if (required)
          const Text(
            " *",
            style: TextStyle(color: Colors.red, fontSize: 14),
          ),
      ],
    );
  }

  InputDecoration _inputDecoration(String hint) => InputDecoration(
        hintText: hint,
        hintStyle: MyTextStyle.bodySmall(xMuted: true),
        filled: true,
        fillColor: Colors.grey.shade100,
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide(color: Colors.grey.shade300),
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide(color: Colors.grey.shade300),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: const BorderSide(color: Colors.blueAccent, width: 1.5),
        ),
        contentPadding:
            const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        isDense: true,
      );

  Widget _textField(String label, TextEditingController ctrl,
      {bool required = false, int maxLines = 1}) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _labelWithStar(label, required: required),
        MySpacing.height(8),
        TextFormField(
          controller: ctrl,
          maxLines: maxLines,
          decoration: _inputDecoration("Enter $label"),
          validator: required
              ? (v) =>
                  (v == null || v.trim().isEmpty) ? "$label is required" : null
              : null,
        ),
      ],
    );
  }

  Widget _popupSelector(RxString selected, List<String> options, String hint) =>
      Obx(() {
        return GestureDetector(
          onTap: () async {
            final selectedItem = await showMenu<String>(
              context: context,
              position: RelativeRect.fromLTRB(100, 300, 100, 0),
              items: options
                  .map((e) => PopupMenuItem<String>(value: e, child: Text(e)))
                  .toList(),
            );
            if (selectedItem != null) selected.value = selectedItem;
          },
          child: Container(
            height: 48,
            padding: const EdgeInsets.symmetric(horizontal: 16),
            decoration: BoxDecoration(
              color: Colors.grey.shade100,
              borderRadius: BorderRadius.circular(12),
              border: Border.all(color: Colors.grey.shade300),
            ),
            alignment: Alignment.centerLeft,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(selected.value.isNotEmpty ? selected.value : hint,
                    style: const TextStyle(fontSize: 14)),
                const Icon(Icons.expand_more, size: 20),
              ],
            ),
          ),
        );
      });

  Widget _dynamicList(
      RxList<TextEditingController> ctrls,
      RxList<RxString> labels,
      String labelType,
      List<String> labelOptions,
      TextInputType type) {
    return Obx(() {
      return Column(
        children: List.generate(ctrls.length, (i) {
          return Padding(
            padding: const EdgeInsets.only(bottom: 12),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      MyText.labelMedium("$labelType Label"),
                      MySpacing.height(8),
                      _popupSelector(labels[i], labelOptions, "Label"),
                    ],
                  ),
                ),
                MySpacing.width(12),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      MyText.labelMedium(labelType),
                      MySpacing.height(8),
                      TextFormField(
                        controller: ctrls[i],
                        keyboardType: type,
                        maxLength: type == TextInputType.phone ? 10 : null,
                        inputFormatters: type == TextInputType.phone
                            ? [FilteringTextInputFormatter.digitsOnly]
                            : [],
                        decoration:
                            _inputDecoration("Enter $labelType").copyWith(
                          counterText: "",
                          suffixIcon: type == TextInputType.phone
                              ? IconButton(
                                  icon: const Icon(Icons.contact_phone,
                                      color: Colors.blue),
                                  onPressed: () async {
                                    final phone = await ContactPickerHelper
                                        .pickIndianPhoneNumber(context);
                                    if (phone != null) ctrls[i].text = phone;
                                  },
                                )
                              : null,
                        ),
                        validator: (value) {
                          if (value == null || value.trim().isEmpty)
                            return null;
                          final trimmed = value.trim();
                          if (type == TextInputType.phone &&
                              !RegExp(r'^[1-9][0-9]{9}$').hasMatch(trimmed)) {
                            return "Enter valid phone number";
                          }
                          if (type == TextInputType.emailAddress &&
                              !RegExp(r'^[\w.-]+@([\w-]+\.)+[\w-]{2,4}$')
                                  .hasMatch(trimmed)) {
                            return "Enter valid email";
                          }
                          return null;
                        },
                      ),
                    ],
                  ),
                ),
                if (ctrls.length > 1)
                  Padding(
                    padding: const EdgeInsets.only(top: 24),
                    child: IconButton(
                      icon: const Icon(Icons.remove_circle_outline,
                          color: Colors.red),
                      onPressed: () {
                        ctrls.removeAt(i);
                        labels.removeAt(i);
                      },
                    ),
                  ),
              ],
            ),
          );
        }),
      );
    });
  }

  Widget _tagInput() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(
          height: 48,
          child: TextField(
            controller: tagCtrl,
            onChanged: (value) {
              
              if (value.endsWith(" ") || value.endsWith(",")) {
                final cleaned = value.trim().replaceAll(",", "");
                if (cleaned.isNotEmpty) {
                  controller.addEnteredTag(cleaned);
                }
                tagCtrl.clear();
                controller.clearSuggestions();
              } else {
                controller.filterSuggestions(value);
              }
            },
            onSubmitted: (v) {
              if (v.trim().isNotEmpty) {
                controller.addEnteredTag(v.trim());
              }
              tagCtrl.clear();
              controller.clearSuggestions();
            },
            decoration: _inputDecoration("Start typing to add tags"),
          ),
        ),

        
        Obx(() => controller.filteredSuggestions.isEmpty
            ? const SizedBox.shrink()
            : Container(
                margin: const EdgeInsets.only(top: 4),
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(color: Colors.grey.shade300),
                  borderRadius: BorderRadius.circular(8),
                  boxShadow: const [
                    BoxShadow(color: Colors.black12, blurRadius: 4)
                  ],
                ),
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: controller.filteredSuggestions.length,
                  itemBuilder: (_, i) {
                    final suggestion = controller.filteredSuggestions[i];
                    return ListTile(
                      dense: true,
                      title: Text(suggestion),
                      onTap: () {
                        controller.addEnteredTag(suggestion);
                        tagCtrl.clear();
                        controller.clearSuggestions();
                      },
                    );
                  },
                ),
              )),

        MySpacing.height(8),

        // TAG CHIPS
        Obx(() => Wrap(
              spacing: 8,
              children: controller.enteredTags
                  .map((tag) => Chip(
                        label: Text(tag),
                        onDeleted: () => controller.removeEnteredTag(tag),
                      ))
                  .toList(),
            )),
      ],
    );
  }

  Widget _bucketMultiSelectField() {
    return _multiSelectField(
      items: controller.buckets
          .map((name) => FilterItem(id: name, name: name))
          .toList(),
      fallback: "Choose Buckets",
      selectedValues: controller.selectedBuckets,
    );
  }

  Widget _multiSelectField({
    required List<FilterItem> items,
    required String fallback,
    required RxList<String> selectedValues,
  }) {
    if (items.isEmpty) return const SizedBox.shrink();

    return Obx(() {
      final selectedNames = items
          .where((f) => selectedValues.contains(f.id))
          .map((f) => f.name)
          .join(", ");
      final displayText = selectedNames.isNotEmpty ? selectedNames : fallback;

      return Builder(
        builder: (context) {
          return GestureDetector(
            onTap: () async {
              final RenderBox button = context.findRenderObject() as RenderBox;
              final RenderBox overlay =
                  Overlay.of(context).context.findRenderObject() as RenderBox;
              final position = button.localToGlobal(Offset.zero);

              await showMenu(
                context: context,
                position: RelativeRect.fromLTRB(
                  position.dx,
                  position.dy + button.size.height,
                  overlay.size.width - position.dx - button.size.width,
                  0,
                ),
                items: [
                  PopupMenuItem(
                    enabled: false,
                    child: StatefulBuilder(
                      builder: (context, setState) {
                        return SizedBox(
                          width: 250,
                          child: SingleChildScrollView(
                            child: Column(
                              mainAxisSize: MainAxisSize.min,
                              children: items.map((f) {
                                final isChecked = selectedValues.contains(f.id);
                                return CheckboxListTile(
                                  dense: true,
                                  title: Text(f.name),
                                  value: isChecked,
                                  contentPadding: EdgeInsets.zero,
                                  controlAffinity:
                                      ListTileControlAffinity.leading,
                                  side: const BorderSide(
                                      color: Colors.black, width: 1.5),
                                  fillColor:
                                      MaterialStateProperty.resolveWith<Color>(
                                          (states) {
                                    if (states
                                        .contains(MaterialState.selected)) {
                                      return Colors.indigo; // selected color
                                    }
                                    return Colors
                                        .white; // unselected background
                                  }),
                                  checkColor: Colors.white, // tick color
                                  onChanged: (val) {
                                    if (val == true) {
                                      selectedValues.add(f.id);
                                    } else {
                                      selectedValues.remove(f.id);
                                    }
                                    setState(() {});
                                  },
                                );
                              }).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(
                      displayText,
                      style: const TextStyle(color: Colors.black87),
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                  const Icon(Icons.arrow_drop_down, color: Colors.grey),
                ],
              ),
            ),
          );
        },
      );
    });
  }

  void _handleSubmit() {
    bool valid = formKey.currentState?.validate() ?? false;

    if (controller.selectedBuckets.isEmpty) {
      bucketError.value = "Bucket is required";
      valid = false;
    } else {
      bucketError.value = "";
    }

    if (!valid) return;

    final emails = emailCtrls
        .asMap()
        .entries
        .where((e) => e.value.text.trim().isNotEmpty)
        .map((e) => {
              "label": emailLabels[e.key].value,
              "emailAddress": e.value.text.trim()
            })
        .toList();

    final phones = phoneCtrls
        .asMap()
        .entries
        .where((e) => e.value.text.trim().isNotEmpty)
        .map((e) => {
              "label": phoneLabels[e.key].value,
              "phoneNumber": e.value.text.trim()
            })
        .toList();

    controller.submitContact(
      id: widget.existingContact?.id,
      name: nameCtrl.text.trim(),
      organization: orgCtrl.text.trim(),
      emails: emails,
      phones: phones,
      address: addrCtrl.text.trim(),
      description: descCtrl.text.trim(),
      designation: designationCtrl.text.trim(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      if (!controller.isInitialized.value) {
        return const Center(child: CircularProgressIndicator());
      }

      return BaseBottomSheet(
        title: widget.existingContact != null
            ? "Edit Contact"
            : "Create New Contact",
        onCancel: () => Get.back(),
        onSubmit: _handleSubmit,
        isSubmitting: controller.isSubmitting.value,
        child: Form(
          key: formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _textField("Name", nameCtrl, required: true),
              MySpacing.height(16),
              _textField("Organization", orgCtrl, required: true),
              MySpacing.height(16),
              _labelWithStar("Buckets", required: true),
              MySpacing.height(8),
              Stack(
                children: [
                  _bucketMultiSelectField(),
                ],
              ),
              MySpacing.height(12),
              Obx(() => GestureDetector(
                    onTap: () => showAdvanced.toggle(),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        MyText.labelLarge("Advanced Details (Optional)",
                            fontWeight: 600),
                        Icon(showAdvanced.value
                            ? Icons.expand_less
                            : Icons.expand_more),
                      ],
                    ),
                  )),
              Obx(() => showAdvanced.value
                  ? Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        MySpacing.height(24),
                        _dynamicList(
                            emailCtrls,
                            emailLabels,
                            "Email",
                            ["Office", "Personal", "Other"],
                            TextInputType.emailAddress),
                        TextButton.icon(
                          onPressed: () {
                            emailCtrls.add(TextEditingController());
                            emailLabels.add("Office".obs);
                          },
                          icon: const Icon(Icons.add),
                          label: const Text("Add Email"),
                        ),
                        _dynamicList(phoneCtrls, phoneLabels, "Phone",
                            ["Work", "Mobile", "Other"], TextInputType.phone),
                        TextButton.icon(
                          onPressed: () {
                            phoneCtrls.add(TextEditingController());
                            phoneLabels.add("Work".obs);
                          },
                          icon: const Icon(Icons.add),
                          label: const Text("Add Phone"),
                        ),
                        Obx(() => showAdvanced.value
                            ? Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  // ✅ Move Designation field here
                                  _textField("Designation", designationCtrl),
                                  MySpacing.height(16),

                                  _dynamicList(
                                    emailCtrls,
                                    emailLabels,
                                    "Email",
                                    ["Office", "Personal", "Other"],
                                    TextInputType.emailAddress,
                                  ),
                                  TextButton.icon(
                                    onPressed: () {
                                      emailCtrls.add(TextEditingController());
                                      emailLabels.add("Office".obs);
                                    },
                                    icon: const Icon(Icons.add),
                                    label: const Text("Add Email"),
                                  ),
                                  _dynamicList(
                                    phoneCtrls,
                                    phoneLabels,
                                    "Phone",
                                    ["Work", "Mobile", "Other"],
                                    TextInputType.phone,
                                  ),
                                  TextButton.icon(
                                    onPressed: () {
                                      phoneCtrls.add(TextEditingController());
                                      phoneLabels.add("Work".obs);
                                    },
                                    icon: const Icon(Icons.add),
                                    label: const Text("Add Phone"),
                                  ),
                                  MyText.labelMedium("Category"),
                                  MySpacing.height(8),
                                  _popupSelector(
                                    controller.selectedCategory,
                                    controller.categories,
                                    "Choose Category",
                                  ),
                                  MySpacing.height(16),
                                  MyText.labelMedium("Tags"),
                                  MySpacing.height(8),
                                  _tagInput(),
                                  MySpacing.height(16),
                                  _textField("Address", addrCtrl),
                                  MySpacing.height(16),
                                  _textField("Description", descCtrl,
                                      maxLines: 3),
                                ],
                              )
                            : const SizedBox.shrink()),
                      ],
                    )
                  : const SizedBox.shrink()),
            ],
          ),
        ),
      );
    });
  }
}

class FilterItem {
  final String id;
  final String name;
  FilterItem({required this.id, required this.name});
}
