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

import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart';
import 'package:on_field_work/helpers/utils/attendance_actions.dart';
import 'package:on_field_work/controller/project_controller.dart';
import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart';

class AttendanceActionButton extends StatefulWidget {
  final dynamic employee;
  final AttendanceController attendanceController;

  const AttendanceActionButton({
    super.key,
    required this.employee,
    required this.attendanceController,
  });

  @override
  State<AttendanceActionButton> createState() => _AttendanceActionButtonState();
}

class _AttendanceActionButtonState extends State<AttendanceActionButton> {
  final attendanceController = Get.find<AttendanceController>();
  late final String uniqueLogKey;

  @override
  void initState() {
    super.initState();
    uniqueLogKey = AttendanceButtonHelper.getUniqueKey(
      widget.employee.employeeId,
      widget.employee.id,
    );

    WidgetsBinding.instance.addPostFrameCallback((_) {
      widget.attendanceController.uploadingStates.putIfAbsent(
        uniqueLogKey,
        () => false.obs,
      );
    });
  }

  Future<DateTime?> _pickRegularizationTime(DateTime referenceTime) async {
    final pickedTime = await showTimePicker(
      context: context,
      initialTime:
          TimeOfDay.fromDateTime(referenceTime), // start from actual log time
    );

    if (pickedTime == null) return null;

    final selected = DateTime(
      referenceTime.year,
      referenceTime.month,
      referenceTime.day,
      pickedTime.hour,
      pickedTime.minute,
    );

    final now = DateTime.now();

    // Allow times before check-in for regularization, but never future
    if (selected.isAfter(now)) {
      showAppSnackbar(
        title: "Invalid Time",
        message: "Future time is not allowed.",
        type: SnackbarType.warning,
      );
      return null;
    }

    return selected;
  }

  Future<void> _handleButtonPressed() async {
    final controller = widget.attendanceController;
    final projectController = Get.find<ProjectController>();
    final selectedProjectId = projectController.selectedProject?.id;

    if (selectedProjectId == null) {
      showAppSnackbar(
        title: "Project Required",
        message: "Please select a project first",
        type: SnackbarType.error,
      );
      return;
    }

    controller.uploadingStates[uniqueLogKey]?.value = true;

    int action;
    String actionText;
    bool imageCapture = true;

    switch (widget.employee.activity) {
      case 0:
      case 4:
        action = 0;
        actionText = ButtonActions.checkIn;
        break;

      case 1:
        final isOldCheckIn =
            AttendanceButtonHelper.isOlderThanDays(widget.employee.checkIn, 2);
        final isOldCheckOut =
            AttendanceButtonHelper.isOlderThanDays(widget.employee.checkOut, 2);

        if (widget.employee.checkOut == null && isOldCheckIn) {
          action = 2;
          actionText = ButtonActions.requestRegularize;
          imageCapture = false;
        } else if (widget.employee.checkOut != null && isOldCheckOut) {
          action = 2;
          actionText = ButtonActions.requestRegularize;
        } else {
          action = 1;
          actionText = ButtonActions.checkOut;
        }
        break;

      case 2:
        action = 2;
        actionText = ButtonActions.requestRegularize;
        break;

      default:
        action = 0;
        actionText = "Unknown Action";
        break;
    }

    DateTime? selectedTime;

    final isYesterdayCheckIn = widget.employee.checkIn != null &&
        DateUtils.isSameDay(
          widget.employee.checkIn,
          DateTime.now().subtract(const Duration(days: 1)),
        );

    if (isYesterdayCheckIn &&
        widget.employee.checkOut == null &&
        actionText == ButtonActions.checkOut) {
      selectedTime = await _pickRegularizationTime(widget.employee.checkIn!);
      if (selectedTime == null) {
        controller.uploadingStates[uniqueLogKey]?.value = false;
        return;
      }
    }

    final comment = await _showCommentBottomSheet(
      context,
      actionText,
      selectedTime: selectedTime,
      checkInDate: widget.employee.checkIn,
    );
    if (comment == null || comment.isEmpty) {
      controller.uploadingStates[uniqueLogKey]?.value = false;
      return;
    }

    String? markTime;
    if (actionText == ButtonActions.requestRegularize) {
      selectedTime ??= await _pickRegularizationTime(widget.employee.checkIn!);
      markTime = selectedTime != null
          ? DateFormat("hh:mm a").format(selectedTime)
          : null;
    } else if (selectedTime != null) {
      markTime = DateFormat("hh:mm a").format(selectedTime);
    }

    final success = await controller.captureAndUploadAttendance(
      widget.employee.id,
      widget.employee.employeeId,
      selectedProjectId,
      comment: comment,
      action: action,
      imageCapture: imageCapture,
      markTime: markTime,
    );

    showAppSnackbar(
      title: success ? '${capitalizeFirstLetter(actionText)} Success' : 'Error',
      message: success
          ? '${capitalizeFirstLetter(actionText)} marked successfully!'
          : 'Failed to ${actionText.toLowerCase()}',
      type: success ? SnackbarType.success : SnackbarType.error,
    );

    controller.uploadingStates[uniqueLogKey]?.value = false;

    if (selectedProjectId.isNotEmpty) {
      await attendanceController.fetchProjectData(selectedProjectId);
      attendanceController.update(['attendance_dashboard_controller']);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      final controller = widget.attendanceController;
      final isUploading =
          controller.uploadingStates[uniqueLogKey]?.value ?? false;
      final emp = widget.employee;

      final isYesterday =
          AttendanceButtonHelper.isLogFromYesterday(emp.checkIn, emp.checkOut);
      final isTodayApproved =
          AttendanceButtonHelper.isTodayApproved(emp.activity, emp.checkIn);
      final isApprovedButNotToday =
          AttendanceButtonHelper.isApprovedButNotToday(
              emp.activity, isTodayApproved);

      final isButtonDisabled = AttendanceButtonHelper.isButtonDisabled(
        isUploading: isUploading,
        isYesterday: isYesterday,
        activity: emp.activity,
        isApprovedButNotToday: isApprovedButNotToday,
      );

      final buttonText = AttendanceButtonHelper.getButtonText(
        activity: emp.activity,
        checkIn: emp.checkIn,
        checkOut: emp.checkOut,
        isTodayApproved: isTodayApproved,
      );

      final primary = AttendanceButtonHelper.getprimary(
        isYesterday: isYesterday,
        isTodayApproved: isTodayApproved,
        activity: emp.activity,
      );

      return AttendanceActionButtonUI(
        isUploading: isUploading,
        isButtonDisabled: isButtonDisabled,
        buttonText: buttonText,
        primary: primary,
        onPressed: isButtonDisabled ? null : _handleButtonPressed,
      );
    });
  }
}

class AttendanceActionButtonUI extends StatelessWidget {
  final bool isUploading;
  final bool isButtonDisabled;
  final String buttonText;
  final Color primary;
  final VoidCallback? onPressed;

  const AttendanceActionButtonUI({
    super.key,
    required this.isUploading,
    required this.isButtonDisabled,
    required this.buttonText,
    required this.primary,
    required this.onPressed,
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 30,
      child: ElevatedButton(
        onPressed: onPressed,
        style: ElevatedButton.styleFrom(
          backgroundColor: primary,
          padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
          textStyle: const TextStyle(fontSize: 12),
        ),
        child: isUploading
            ? const Text(
                'Loading...',
                style: TextStyle(fontSize: 12, color: Colors.white),
              )
            : Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  if (buttonText.toLowerCase() == 'approved')
                    const Icon(Icons.check, size: 16, color: Colors.green),
                  if (buttonText.toLowerCase() == 'rejected')
                    const Icon(Icons.close, size: 16, color: Colors.red),
                  if (buttonText.toLowerCase() == 'requested')
                    const Icon(Icons.hourglass_top,
                        size: 16, color: Colors.orange),
                  if (['approved', 'rejected', 'requested']
                      .contains(buttonText.toLowerCase()))
                    const SizedBox(width: 4),
                  Flexible(
                    child: Text(
                      buttonText,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(fontSize: 12),
                    ),
                  ),
                ],
              ),
      ),
    );
  }
}

Future<String?> _showCommentBottomSheet(
  BuildContext context,
  String actionText, {
  DateTime? selectedTime,
  DateTime? checkInDate,
}) async {
  final commentController = TextEditingController();
  String? errorText;

  // Prepare title
  String sheetTitle = "Add Comment for ${capitalizeFirstLetter(actionText)}";
  if (selectedTime != null && checkInDate != null) {
    sheetTitle =
        "${capitalizeFirstLetter(actionText)} for ${DateFormat('dd MMM yyyy').format(checkInDate)} at ${DateFormat('hh:mm a').format(selectedTime)}";
  }

  return showModalBottomSheet<String>(
    context: context,
    isScrollControlled: true,
    backgroundColor: Colors.transparent,
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
    ),
    builder: (context) {
      return StatefulBuilder(
        builder: (context, setModalState) {
          void submit() {
            final comment = commentController.text.trim();
            if (comment.isEmpty) {
              setModalState(() => errorText = 'Comment cannot be empty.');
              return;
            }
            Navigator.of(context).pop(comment);
          }

          return Padding(
            padding: EdgeInsets.only(
                bottom: MediaQuery.of(context).viewInsets.bottom),
            child: BaseBottomSheet(
              title: sheetTitle, // 👈 now showing full sentence as title
              onCancel: () => Navigator.of(context).pop(),
              onSubmit: submit,
              isSubmitting: false,
              submitText: 'Submit',
              child: TextField(
                controller: commentController,
                maxLines: 4,
                decoration: InputDecoration(
                  hintText: 'Type your comment here...',
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(8),
                  ),
                  filled: true,
                  fillColor: Colors.grey.shade100,
                  errorText: errorText,
                ),
                onChanged: (_) {
                  if (errorText != null) {
                    setModalState(() => errorText = null);
                  }
                },
              ),
            ),
          );
        },
      );
    },
  );
}

String capitalizeFirstLetter(String text) =>
    text.isEmpty ? text : text[0].toUpperCase() + text.substring(1);
