import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:on_field_work/controller/service_project/service_project_details_screen_controller.dart';
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.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/utils/date_time_utils.dart';
import 'package:timeline_tile/timeline_tile.dart';
import 'package:on_field_work/model/service_project/service_project_job_detail_model.dart';
import 'package:on_field_work/helpers/widgets/custom_app_bar.dart';
import 'package:on_field_work/helpers/services/api_service.dart';
import 'package:on_field_work/helpers/widgets/date_range_picker.dart';
import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart';
import 'package:on_field_work/model/employees/employee_model.dart';
import 'package:on_field_work/model/expense/comment_bottom_sheet.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
import 'package:on_field_work/model/service_project/job_status_response.dart';
import 'package:on_field_work/helpers/widgets/serviceProject/add_comment_widget.dart';

class JobDetailsScreen extends StatefulWidget {
  final String jobId;
  final String? projectName;
  const JobDetailsScreen({super.key, required this.jobId, this.projectName});

  @override
  State<JobDetailsScreen> createState() => _JobDetailsScreenState();
}

class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
  late final ServiceProjectDetailsController controller;
  final RxBool isAttendanceExpanded = false.obs;
  RxBool isAttendanceLogLoading = false.obs;

  final TextEditingController _titleController = TextEditingController();
  final TextEditingController _descriptionController = TextEditingController();
  final TextEditingController _startDateController = TextEditingController();
  final TextEditingController _dueDateController = TextEditingController();
  final TextEditingController _tagTextController = TextEditingController();

  final RxList<Assignee> _selectedAssignees = <Assignee>[].obs;
  final RxList<Tag> _selectedTags = <Tag>[].obs;
  final RxBool isEditing = false.obs;
  File? imageAttachment;

  @override
  void initState() {
    super.initState();
    controller = Get.find<ServiceProjectDetailsController>();

    // Fetch job detail first
    controller.fetchJobDetail(widget.jobId).then((_) async {
      final job = controller.jobDetail.value?.data;
      if (job != null) {
        // Populate form fields
        _selectedTags.value =
            (job.tags ?? []).map((t) => Tag(id: t.id, name: t.name)).toList();
        _titleController.text = job.title ?? '';
        _descriptionController.text = job.description ?? '';
        _startDateController.text = DateTimeUtils.convertUtcToLocal(
            job.startDate ?? DateTime.now().toIso8601String(),
            format: "yyyy-MM-dd");
        _dueDateController.text = DateTimeUtils.convertUtcToLocal(
            job.dueDate ?? '',
            format: "yyyy-MM-dd");
        _selectedAssignees.value = job.assignees ?? [];

        // 🔹 Fetch job status only if existing status ID present
        final existingStatusId = job.status?.id;
        if (existingStatusId != null) {
          await controller.fetchJobStatus(statusId: existingStatusId);

          // Set selectedJobStatus to match existing status ID
          if (controller.jobStatusList.isNotEmpty) {
            controller.selectedJobStatus.value =
                controller.jobStatusList.firstWhere(
              (s) => s.id == existingStatusId,
              orElse: () => controller.jobStatusList.first,
            );
          }
        }
      }
    });
  }

  @override
  void dispose() {
    _titleController.dispose();
    _descriptionController.dispose();
    _startDateController.dispose();
    _dueDateController.dispose();
    _tagTextController.dispose();
    super.dispose();
  }

  bool _tagsAreDifferent(List<Tag> original, List<Tag> current) {
    // Compare by id / name sets (simple equality)
    final origIds = original.map((t) => t.id ?? '').toSet();
    final currIds = current.map((t) => t.id ?? '').toSet();
    final origNames = original.map((t) => t.name?.trim() ?? '').toSet();
    final currNames = current.map((t) => t.name?.trim() ?? '').toSet();

    return !(origIds == currIds && origNames == currNames);
  }

  Future<void> _editJob() async {
    _processTagsInput(); // process any new tag input
    final job = controller.jobDetail.value?.data;
    if (job == null) return;

    final List<Map<String, dynamic>> operations = [];

    // 1️⃣ Title
    final trimmedTitle = _titleController.text.trim();
    if (trimmedTitle != job.title) {
      operations
          .add({"op": "replace", "path": "/title", "value": trimmedTitle});
    }

    // 2️⃣ Description
    final trimmedDescription = _descriptionController.text.trim();
    if (trimmedDescription != job.description) {
      operations.add({
        "op": "replace",
        "path": "/description",
        "value": trimmedDescription
      });
    }

    // 3️⃣ Start & Due Date
    final startDate = DateTime.tryParse(_startDateController.text);
    final dueDate = DateTime.tryParse(_dueDateController.text);

    if (startDate != null && startDate.toUtc() != job.startDate) {
      operations.add({
        "op": "replace",
        "path": "/startDate",
        "value": startDate.toUtc().toIso8601String()
      });
    }

    if (dueDate != null && dueDate.toUtc() != job.dueDate) {
      operations.add({
        "op": "replace",
        "path": "/dueDate",
        "value": dueDate.toUtc().toIso8601String()
      });
    }

    // 4️⃣ Assignees
    final originalAssignees = job.assignees ?? [];
    final assigneesPayload = originalAssignees.map((a) {
      final isSelected = _selectedAssignees.any((s) => s.id == a.id);
      return {"employeeId": a.id, "isActive": isSelected};
    }).toList();

    for (var s in _selectedAssignees) {
      if (!originalAssignees.any((a) => a.id == s.id)) {
        assigneesPayload.add({"employeeId": s.id, "isActive": true});
      }
    }
    operations.add(
        {"op": "replace", "path": "/assignees", "value": assigneesPayload});

    // 5️⃣ Tags
    final originalTags = job.tags ?? [];
    final currentTags = _selectedTags.toList();
    if (_tagsAreDifferent(originalTags, currentTags)) {
      final List<Map<String, dynamic>> finalTagsPayload = [];

      for (var ot in originalTags) {
        final isSelected = currentTags.any((ct) =>
            (ct.id != null && ct.id == ot.id) ||
            (ct.name?.trim() == ot.name?.trim()));
        finalTagsPayload.add({
          "id": ot.id,
          "name": ot.name,
          "isActive": isSelected,
        });
      }

      for (var ct in currentTags.where((c) => c.id == null || c.id == "0")) {
        finalTagsPayload.add({"name": ct.name, "isActive": true});
      }

      operations
          .add({"op": "replace", "path": "/tags", "value": finalTagsPayload});
    }

    // 6️⃣ Job Status
    final selectedStatus = controller.selectedJobStatus.value;
    if (selectedStatus != null && selectedStatus.id != job.status?.id) {
      operations.add({
        "op": "replace",
        "path": "/statusId", // make sure API expects this field
        "value": selectedStatus.id
      });
    }

    // 7️⃣ Check if anything changed
    if (operations.isEmpty) {
      showAppSnackbar(
          title: "Info",
          message: "No changes detected to save.",
          type: SnackbarType.info);
      return;
    }

    // 8️⃣ Call API
    final success = await ApiService.editServiceProjectJobApi(
      jobId: job.id ?? "",
      operations: operations,
    );

    if (success) {
      showAppSnackbar(
          title: "Success",
          message: "Job updated successfully",
          type: SnackbarType.success);

      // Re-fetch job detail & update tags locally
      await controller.fetchJobDetail(widget.jobId);
      final updatedJob = controller.jobDetail.value?.data;
      if (updatedJob != null) {
        _selectedTags.value = (updatedJob.tags ?? [])
            .map((t) => Tag(id: t.id, name: t.name))
            .toList();
        setState(() {});
      }

      isEditing.value = false;
    } else {
      showAppSnackbar(
          title: "Error",
          message: "Failed to update job. Check inputs or try again.",
          type: SnackbarType.error);
    }
  }

  void _processTagsInput() {
    final input = _tagTextController.text;

    // Remove comma behaviour → treat whole input as one tag
    String tag = input.trim();
    if (tag.isEmpty) {
      _tagTextController.clear();
      return;
    }

    // Convert underscore to space
    tag = tag.replaceAll("_", " ");

    // Avoid duplicate tags (case-insensitive)
    if (!_selectedTags
        .any((t) => (t.name ?? "").toLowerCase() == tag.toLowerCase())) {
      _selectedTags.add(Tag(id: "0", name: tag));
    }

    // Clear text field
    _tagTextController.clear();
  }

  Future<void> _handleTagAction() async {
    final job = controller.jobDetail.value?.data;
    if (job == null) return;

    final action = job.nextTaggingAction;
    File? attachmentFile;

    final comment = await showCommentBottomSheet(
        context, action == 0 ? "Tag In" : "Tag Out");
    if (comment == null) return;

    await showDialog(
      context: context,
      builder: (_) => ConfirmDialog(
        title: "Attach Image?",
        message: "Do you want to attach an image for this action?",
        confirmText: "Yes",
        cancelText: "No",
        icon: Icons.camera_alt_outlined,
        confirmColor: Colors.blueAccent,
        onConfirm: () async {
          final picker = ImagePicker();
          final picked = await picker.pickImage(source: ImageSource.camera);
          if (picked != null) {
            attachmentFile = File(picked.path);
          }
        },
      ),
    );

    await controller.updateJobAttendance(
      jobId: job.id ?? "",
      action: action == 0 ? 0 : 1,
      comment: comment,
      attachment: attachmentFile,
    );

    final msg = controller.attendanceMessage.value;
    if (msg.toLowerCase().contains("failed") ||
        msg.toLowerCase().contains("error")) {
      showAppSnackbar(title: "Error", message: msg, type: SnackbarType.error);
      return;
    }

    showAppSnackbar(title: "Success", message: msg, type: SnackbarType.success);
  }

  Widget _buildSectionCard({
    required String title,
    required IconData titleIcon,
    required List<Widget> children,
  }) {
    return Card(
      elevation: 3,
      shadowColor: Colors.black12,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      margin: const EdgeInsets.symmetric(vertical: 8),
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          Row(children: [
            Icon(titleIcon, size: 20, color: Colors.blueAccent),
            MySpacing.width(8),
            MyText.bodyLarge(title, fontWeight: 700, fontSize: 16),
          ]),
          MySpacing.height(8),
          const Divider(),
          ...children,
        ]),
      ),
    );
  }

  Widget _editableRow(String label, TextEditingController controller) {
    return Obx(() {
      final editing = isEditing.value;
      return Padding(
        padding: const EdgeInsets.symmetric(vertical: 8),
        child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          MyText.bodySmall(label, color: Colors.grey[600], fontWeight: 600),
          const SizedBox(height: 6),
          editing
              ? TextField(
                  controller: controller,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(5)),
                    isDense: true,
                    contentPadding: const EdgeInsets.symmetric(
                        horizontal: 10, vertical: 12),
                  ),
                )
              : Container(
                  width: double.infinity,
                  padding:
                      const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
                  decoration: BoxDecoration(
                      color: Colors.grey.shade100,
                      borderRadius: BorderRadius.circular(5)),
                  child: Text(controller.text,
                      style: const TextStyle(fontSize: 14)),
                ),
        ]),
      );
    });
  }

  Widget _dateRangePicker() {
    return Obx(() {
      final editing = isEditing.value;
      final startDate =
          DateTime.tryParse(_startDateController.text) ?? DateTime.now();
      final dueDate = DateTime.tryParse(_dueDateController.text) ??
          DateTime.now().add(const Duration(days: 1));
      return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
        MyText.bodySmall("Select Date Range",
            color: Colors.grey[600], fontWeight: 600),
        const SizedBox(height: 8),
        editing
            ? DateRangePickerWidget(
                startDate: Rx<DateTime>(startDate),
                endDate: Rx<DateTime>(dueDate),
                startLabel: "Start Date",
                endLabel: "Due Date",
                onDateRangeSelected: (start, end) {
                  if (start != null && end != null) {
                    _startDateController.text =
                        start.toIso8601String().split("T").first;
                    _dueDateController.text =
                        end.toIso8601String().split("T").first;
                  }
                },
              )
            : Container(
                width: double.infinity,
                padding:
                    const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
                decoration: BoxDecoration(
                    color: Colors.grey.shade100,
                    borderRadius: BorderRadius.circular(5)),
                child: Text(
                    "${_startDateController.text} → ${_dueDateController.text}"),
              ),
      ]);
    });
  }

  Widget _assigneeInputWithChips() {
    return Obx(() {
      final editing = isEditing.value;
      final assignees = _selectedAssignees;
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (assignees.isNotEmpty)
            Wrap(
              spacing: 6,
              children: assignees
                  .map(
                    (a) => Chip(
                      label: Text("${a.firstName} ${a.lastName}"),
                      onDeleted: editing
                          ? () {
                              _selectedAssignees.remove(a);
                            }
                          : null,
                    ),
                  )
                  .toList(),
            ),
          const SizedBox(height: 8),
          if (editing)
            GestureDetector(
              onTap: () async {
                final initiallySelected = assignees.map<EmployeeModel>((a) {
                  return EmployeeModel(
                    id: a.id ?? '',
                    employeeId: a.id ?? '',
                    firstName: a.firstName ?? '',
                    lastName: a.lastName ?? '',
                    name: "${a.firstName} ${a.lastName}",
                    designation: a.jobRoleName ?? '',
                    jobRole: a.jobRoleName ?? '',
                    jobRoleID: a.jobRoleId ?? '',
                    email: a.email ?? '',
                    phoneNumber: '',
                    activity: 0,
                    action: 0,
                  );
                }).toList();

                final selected =
                    await showModalBottomSheet<List<EmployeeModel>>(
                  context: context,
                  isScrollControlled: true,
                  builder: (_) => EmployeeSelectionBottomSheet(
                    multipleSelection: true,
                    initiallySelected: initiallySelected,
                  ),
                );

                if (selected != null) {
                  _selectedAssignees.value = selected.map((e) {
                    return Assignee(
                      id: e.id,
                      firstName: e.firstName,
                      lastName: e.lastName,
                      email: e.email,
                      photo: '',
                      jobRoleId: e.jobRoleID,
                      jobRoleName: e.jobRole,
                    );
                  }).toList();
                }
              },
              child: Container(
                height: 40,
                padding: const EdgeInsets.symmetric(horizontal: 12),
                decoration: BoxDecoration(
                  color: Colors.grey.shade100,
                  borderRadius: BorderRadius.circular(5),
                  border: Border.all(color: Colors.grey.shade400),
                ),
                alignment: Alignment.centerLeft,
                child: Text("Tap to select assignees",
                    style: TextStyle(fontSize: 14, color: Colors.grey[700])),
              ),
            ),
        ],
      );
    });
  }

  Widget _tagEditor() {
    return Obx(() {
      final editing = isEditing.value;
      final job = controller.jobDetail.value?.data;

      final displayTags = editing ? _selectedTags : (job?.tags ?? []);

      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Wrap(
            spacing: 6,
            children: displayTags
                .map(
                  (t) => Chip(
                    label: Text(t.name ?? ''),
                    onDeleted: editing
                        ? () {
                            _selectedTags.removeWhere((x) =>
                                (x.id != null && x.id == t.id) ||
                                (x.name == t.name));
                          }
                        : null,
                  ),
                )
                .toList(),
          ),
          const SizedBox(height: 8),
          if (editing)
            TextField(
              controller: _tagTextController,
              onChanged: (value) {
                // If space or comma typed → process tags immediately
                if (value.endsWith(" ") || value.contains(",")) {
                  _processTagsInput();
                }
              },
              onSubmitted: (_) {
                // Still supports ENTER
                _processTagsInput();
              },
              decoration: InputDecoration(
                hintText: "Type tags (space or comma to add multiple tags)",
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(5),
                ),
                isDense: true,
                contentPadding:
                    const EdgeInsets.symmetric(horizontal: 10, vertical: 12),
              ),
            ),
        ],
      );
    });
  }

  Widget _buildAttendanceCard() {
    return Obx(() {
      final job = controller.jobDetail.value?.data;
      final isLoading = controller.isTagging.value;
      final action = job?.nextTaggingAction;
      final logs = controller.attendanceLog.value?.data ?? [];

      if (job == null) return const SizedBox();

      return Card(
        elevation: 3,
        shadowColor: Colors.black12,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
        margin: const EdgeInsets.symmetric(vertical: 8),
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Header
              Row(
                children: [
                  Icon(Icons.access_time_outlined,
                      size: 20, color: Colors.blueAccent),
                  const SizedBox(width: 8),
                  MyText.bodyLarge("Attendance", fontWeight: 700, fontSize: 16),
                  const Spacer(),
                  Obx(() => IconButton(
                        icon: Icon(
                            isAttendanceExpanded.value
                                ? Icons.expand_less
                                : Icons.expand_more,
                            color: Colors.grey[600]),
                        onPressed: () async {
                          isAttendanceExpanded.value =
                              !isAttendanceExpanded.value;
                          if (isAttendanceExpanded.value) {
                            await controller
                                .fetchJobAttendanceLog(job.attendanceId ?? '');
                          }
                        },
                      ))
                ],
              ),
              const SizedBox(height: 8),
              const Divider(),

              // Tag In/Tag Out Button
              if (action != null)
                Align(
                  alignment: Alignment.center,
                  child: SizedBox(
                    height: 36,
                    child: ElevatedButton.icon(
                      icon: isLoading
                          ? SizedBox(
                              height: 16,
                              width: 16,
                              child: CircularProgressIndicator(
                                  color: Colors.white, strokeWidth: 2))
                          : Icon(action == 0 ? Icons.login : Icons.logout),
                      label: MyText.bodyMedium(
                          action == 0 ? "Tag In" : "Tag Out",
                          fontWeight: 600,
                          color: Colors.white),
                      onPressed: isLoading ? null : _handleTagAction,
                      style: ElevatedButton.styleFrom(
                        padding: const EdgeInsets.symmetric(horizontal: 20),
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(5)),
                        backgroundColor:
                            action == 0 ? Colors.green : Colors.red,
                      ),
                    ),
                  ),
                ),

              // Attendance Logs
              Obx(() {
                if (!isAttendanceExpanded.value) return Container();

                if (isAttendanceLogLoading.value) {
                  return Padding(
                    padding: const EdgeInsets.symmetric(vertical: 12),
                    child: Center(child: CircularProgressIndicator()),
                  );
                }

                if (logs.isEmpty) {
                  return Padding(
                    padding: const EdgeInsets.only(top: 12),
                    child: MyText.bodyMedium("No attendance logs available",
                        color: Colors.grey[600]),
                  );
                }

                return ListView.separated(
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  padding: const EdgeInsets.only(top: 12),
                  itemCount: logs.length,
                  separatorBuilder: (_, __) => const SizedBox(height: 8),
                  itemBuilder: (_, index) {
                    final log = logs[index];
                    final employeeName =
                        "${log.employee.firstName} ${log.employee.lastName}";
                    final date = DateTimeUtils.convertUtcToLocal(
                        log.markedAt.toIso8601String(),
                        format: 'd MMM yyyy');
                    final time = DateTimeUtils.convertUtcToLocal(
                        log.markedAt.toIso8601String(),
                        format: 'hh:mm a');

                    return Card(
                      elevation: 1,
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8)),
                      child: Padding(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 12, vertical: 8),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            // Top Row: Icon, Employee, Date, Time
                            Row(
                              children: [
                                Icon(
                                    log.action == 0
                                        ? Icons.login
                                        : Icons.logout,
                                    color: log.action == 0
                                        ? Colors.green
                                        : Colors.red,
                                    size: 18),
                                const SizedBox(width: 6),
                                Expanded(
                                    child: Text(employeeName,
                                        style: const TextStyle(
                                            fontWeight: FontWeight.w600))),
                                Text("$date | $time",
                                    style: TextStyle(
                                        fontSize: 12, color: Colors.grey[700])),
                              ],
                            ),
                            const SizedBox(height: 4),

                            // Comment
                            if (log.comment?.isNotEmpty == true)
                              Padding(
                                  padding: const EdgeInsets.only(top: 4),
                                  child: Text(log.comment!,
                                      style: const TextStyle(fontSize: 13))),

                            // Location
                            if (log.latitude != null && log.longitude != null)
                              GestureDetector(
                                onTap: () async {
                                  final lat =
                                      double.tryParse(log.latitude!) ?? 0.0;
                                  final lon =
                                      double.tryParse(log.longitude!) ?? 0.0;
                                  final url =
                                      'https://www.google.com/maps/search/?api=1&query=$lat,$lon';
                                  if (await canLaunchUrl(Uri.parse(url))) {
                                    await launchUrl(Uri.parse(url),
                                        mode: LaunchMode.externalApplication);
                                  }
                                },
                                child: Padding(
                                  padding: const EdgeInsets.only(top: 4),
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    children: const [
                                      Icon(Icons.location_on,
                                          size: 14, color: Colors.blue),
                                      SizedBox(width: 4),
                                      Text("View Location",
                                          style: TextStyle(
                                              fontSize: 12,
                                              color: Colors.blue,
                                              decoration:
                                                  TextDecoration.underline)),
                                    ],
                                  ),
                                ),
                              ),

                            // Attached Image
                            if (log.document != null)
                              Padding(
                                padding: const EdgeInsets.only(top: 4),
                                child: GestureDetector(
                                  onTap: () => showDialog(
                                    context: context,
                                    builder: (_) => Dialog(
                                      child: Image.network(
                                          log.document!.preSignedUrl,
                                          fit: BoxFit.cover,
                                          height: 250,
                                          errorBuilder: (_, __, ___) =>
                                              const Icon(Icons.broken_image,
                                                  size: 50,
                                                  color: Colors.grey)),
                                    ),
                                  ),
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(6),
                                    child: Image.network(
                                      log.document!.thumbPreSignedUrl.isNotEmpty
                                          ? log.document!.thumbPreSignedUrl
                                          : log.document!.preSignedUrl,
                                      height: 50,
                                      width: 50,
                                      fit: BoxFit.cover,
                                      errorBuilder: (_, __, ___) => const Icon(
                                          Icons.broken_image,
                                          size: 40,
                                          color: Colors.grey),
                                    ),
                                  ),
                                ),
                              ),
                          ],
                        ),
                      ),
                    );
                  },
                );
              }),
            ],
          ),
        ),
      );
    });
  }

  Widget _rowItem(String label, String value) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Expanded(
            flex: 3,
            child: MyText.bodySmall(label,
                fontWeight: 600, color: Colors.grey.shade700)),
        Expanded(flex: 5, child: MyText.bodyMedium(value, fontWeight: 500)),
      ],
    );
  }

  Widget _branchDisplay() {
    final job = controller.jobDetail.value?.data;
    final branch = job?.projectBranch;
    if (branch == null) {
      return MyText.labelMedium("No branch assigned");
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _rowItem("Branch Name", branch.branchName ?? "-"),
        MySpacing.height(8),
        _rowItem("Branch Type", branch.branchType ?? "-"),
      ],
    );
  }

  Widget _buildJobStatusCard() {
    final job = controller.jobDetail.value?.data;
    if (job == null) return const SizedBox();

    // Existing status info
    final statusName = job.status?.displayName ?? "N/A";
    Color statusColor;
    switch (job.status?.level) {
      case 1:
        statusColor = Colors.green;
        break;
      case 2:
        statusColor = Colors.orange;
        break;
      case 3:
        statusColor = Colors.blue;
        break;
      case 4:
        statusColor = Colors.red;
        break;
      default:
        statusColor = Colors.grey;
    }

    final editing = isEditing.value;

    // Ensure selectedJobStatus initialized
    if (editing && controller.selectedJobStatus.value == null) {
      final existingStatusId = job.status?.id;
      if (existingStatusId != null && controller.jobStatusList.isNotEmpty) {
        controller.selectedJobStatus.value =
            controller.jobStatusList.firstWhere(
          (s) => s.id == existingStatusId,
          orElse: () => controller.jobStatusList.first,
        );
      }
    }

    return _buildSectionCard(
      title: "Job Status",
      titleIcon: Icons.flag_outlined,
      children: [
        // 1️⃣ Display existing status
        Row(
          children: [
            Container(
              width: 40,
              height: 40,
              decoration: BoxDecoration(
                color: statusColor.withOpacity(0.2),
                shape: BoxShape.circle,
              ),
              child: Icon(Icons.flag, color: statusColor, size: 24),
            ),
            const SizedBox(width: 16),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    statusName,
                    style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                        color: statusColor),
                  ),
                  const SizedBox(height: 2),
                  Text(
                    "Level: ${job.status?.level ?? '-'}",
                    style: TextStyle(fontSize: 12, color: Colors.grey[700]),
                  ),
                ],
              ),
            ),
          ],
        ),

        const SizedBox(height: 16),

        // 2️⃣ PopupMenuButton for new selection
        if (editing)
          Obx(() {
            final selectedStatus = controller.selectedJobStatus.value;
            final statuses = controller.jobStatusList;

            return PopupMenuButton<JobStatus>(
              onSelected: (val) => controller.selectedJobStatus.value = val,
              itemBuilder: (_) => statuses
                  .map(
                    (s) => PopupMenuItem(
                      value: s,
                      child: Text(s.displayName ?? "N/A"),
                    ),
                  )
                  .toList(),
              child: Container(
                padding:
                    const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
                decoration: BoxDecoration(
                  color: Colors.grey.shade100,
                  borderRadius: BorderRadius.circular(12),
                  border: Border.all(color: Colors.grey.shade300),
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      selectedStatus?.displayName ?? "Select Job Status",
                      style:
                          TextStyle(color: Colors.grey.shade700, fontSize: 14),
                    ),
                    const Icon(Icons.arrow_drop_down),
                  ],
                ),
              ),
            );
          }),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    final projectName = widget.projectName;
    final Color appBarColor = contentTheme.primary;

    return Scaffold(
      backgroundColor: const Color(0xFFF5F5F5),
      appBar: CustomAppBar(
        title: "Job Details Screen",
        onBackPressed: () => Get.back(),
        projectName: projectName,
        backgroundColor: appBarColor,
      ),
      floatingActionButton: Obx(() => FloatingActionButton.extended(
            onPressed:
                isEditing.value ? _editJob : () => isEditing.value = true,
            backgroundColor: appBarColor,
            label: MyText.bodyMedium(
              isEditing.value ? "Save" : "Edit",
              color: Colors.white,
              fontWeight: 600,
            ),
            icon: Icon(isEditing.value ? Icons.save : Icons.edit),
          )),
      body: Stack(
        children: [
          Container(
            height: 80,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                colors: [
                  appBarColor,
                  appBarColor.withOpacity(0.0),
                ],
              ),
            ),
          ),

          // Bottom fade (for smooth transition above FAB)
          Align(
            alignment: Alignment.bottomCenter,
            child: Container(
              height: 60, // adjust based on FAB height
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.bottomCenter,
                  end: Alignment.topCenter,
                  colors: [
                    appBarColor.withOpacity(0.05),
                    Colors.transparent,
                  ],
                ),
              ),
            ),
          ),

          // Main scrollable content
          Obx(() {
            if (controller.isJobDetailLoading.value) {
              return const Center(child: CircularProgressIndicator());
            }

            if (controller.jobDetailErrorMessage.value.isNotEmpty) {
              return Center(
                  child: MyText.bodyMedium(
                      controller.jobDetailErrorMessage.value));
            }

            final job = controller.jobDetail.value?.data;
            if (job == null) {
              return Center(child: MyText.bodyMedium("No details available"));
            }

            return SingleChildScrollView(
              padding: MySpacing.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  _buildJobStatusCard(),
                  _buildAttendanceCard(),
                  _buildSectionCard(
                    title: "Job Info",
                    titleIcon: Icons.task_outlined,
                    children: [
                      _editableRow("Title", _titleController),
                      _editableRow("Description", _descriptionController),
                      _dateRangePicker(),
                    ],
                  ),
                  MySpacing.height(12),
                  _buildSectionCard(
                    title: "Project Branch",
                    titleIcon: Icons.account_tree_outlined,
                    children: [_branchDisplay()],
                  ),
                  MySpacing.height(16),
                  _buildSectionCard(
                      title: "Assignees",
                      titleIcon: Icons.person_outline,
                      children: [_assigneeInputWithChips()]),
                  MySpacing.height(16),
                  _buildSectionCard(
                      title: "Tags",
                      titleIcon: Icons.label_outline,
                      children: [_tagEditor()]),
                  MySpacing.height(16),

                  if ((job.updateLogs?.isNotEmpty ?? false))
                    _buildSectionCard(
                        title: "Update Logs",
                        titleIcon: Icons.history,
                        children: [JobTimeline(logs: job.updateLogs ?? [])]),
                  // ⭐ NEW CARD ADDED HERE
                  MySpacing.height(16),
                  if ((job.updateLogs?.isNotEmpty ?? false))
                    _buildSectionCard(
                        title: "Comment Section",
                        titleIcon: Icons.comment_outlined,
                        children: [
                          AddCommentWidget(
                              jobId: job.id ?? "",
                              jobTicketId: job.jobTicketUId ?? ""),
                        ]),
                  // ⭐ END NEW CARD
                  MySpacing.height(80),
                ],
              ),
            );
          }),
        ],
      ),
    );
  }
}

class JobTimeline extends StatelessWidget {
  final List<UpdateLog> logs;
  const JobTimeline({super.key, required this.logs});

  @override
  Widget build(BuildContext context) {
    if (logs.isEmpty)
      return MyText.bodyMedium('No timeline available', color: Colors.grey);

    final reversedLogs = logs.reversed.toList();

    return ListView.builder(
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      itemCount: reversedLogs.length,
      itemBuilder: (_, index) {
        final log = reversedLogs[index];
        final statusName = log.status?.displayName ?? "Created";
        final nextStatusName = log.nextStatus?.displayName ?? "N/A";
        final comment = log.comment ?? '';
        final updatedBy =
            "${log.updatedBy?.firstName ?? ''} ${log.updatedBy?.lastName ?? ''}";
        final f = log.updatedBy?.firstName ?? '';
        final l = log.updatedBy?.lastName ?? '';
        final initials =
            "${f.isNotEmpty ? f[0] : ''}${l.isNotEmpty ? l[0] : ''}";

        return TimelineTile(
          alignment: TimelineAlign.start,
          isFirst: index == 0,
          isLast: index == reversedLogs.length - 1,
          indicatorStyle: const IndicatorStyle(
              width: 16,
              height: 16,
              indicator: DecoratedBox(
                  decoration: BoxDecoration(
                      color: Colors.blue, shape: BoxShape.circle))),
          beforeLineStyle: LineStyle(color: Colors.grey.shade300, thickness: 2),
          endChild: Padding(
            padding: const EdgeInsets.all(12),
            child:
                Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
              MyText.bodyMedium("$statusName → $nextStatusName",
                  fontWeight: 600),
              if (comment.isNotEmpty) ...[
                const SizedBox(height: 8),
                MyText.bodyMedium(comment),
              ],
              const SizedBox(height: 10),
              Row(children: [
                Container(
                    padding:
                        const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                    decoration: BoxDecoration(
                        color: Colors.grey.shade300,
                        borderRadius: BorderRadius.circular(4)),
                    child: MyText.bodySmall(initials, fontWeight: 600)),
                const SizedBox(width: 6),
                Expanded(child: MyText.bodySmall(updatedBy)),
              ]),
              const SizedBox(height: 10),
            ]),
          ),
        );
      },
    );
  }
}
