import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

import '../../Models/hrmModels/attendanceRequestListResponse.dart';
import '../../Models/ordersModels/commonResponse.dart';
import '../../Utils/app_colors.dart';
import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart';

class Attendancelistprovider extends ChangeNotifier {
  attendanceRequestListResponse? _response;
  bool _isLoading = false;
  String? _errorMessage;

  attendanceRequestListResponse? get response => _response;
  bool get isLoading => _isLoading;
  String? get errorMessage => _errorMessage;

  // Filter states
  String _selectedType = "All";
  String _selectedDateRange = "This Month";
  DateTimeRange? _customDateRange;

  String get selectedType => _selectedType;
  String get selectedDateRange => _selectedDateRange;
  DateTimeRange? get customDateRange => _customDateRange;

  // Addition of attendance
  CommonResponse? _addResponse;
  CommonResponse? get addResponse => _addResponse;

  bool _isSubmitting = false;
  bool get isSubmitting => _isSubmitting;

  // Date controllers for filter UI
  final TextEditingController fromDateController = TextEditingController();
  final TextEditingController toDateController = TextEditingController();

  // For manual attendance date field
  final TextEditingController dateController = TextEditingController();
  DateTime? _selectedDate;
  DateTime? get selectedDate => _selectedDate;

  // Type options for filter
  final List<String> typeOptions = ["All", "Check In", "Check Out", "Check In/Out"];

  // Date range options for filter
  final List<String> dateRangeOptions = [
    "All",
    "Today",
    "Yesterday",
    "This Month",
    "Past 7 days",
    "Last Month",
    "Custom",
  ];

  bool isDateValid() {
    if (_selectedDate == null) return false;

    DateTime today = DateTime.now();
    DateTime yesterday = today.subtract(const Duration(days: 1));

    // normalize (remove time part)
    DateTime normalizedSelected = DateTime(_selectedDate!.year, _selectedDate!.month, _selectedDate!.day);
    DateTime normalizedToday = DateTime(today.year, today.month, today.day);
    DateTime normalizedYesterday = DateTime(yesterday.year, yesterday.month, yesterday.day);

    return normalizedSelected == normalizedToday || normalizedSelected == normalizedYesterday;
  }

  String? validateManualAttendance({//its working or not
    required String type,
    required String? checkInTime,
    required String? checkInLoc,
    required File? checkInProof,
    required String? checkOutTime,
    required String? checkOutLoc,
    required File? checkOutProof,
    required String? checkInDesc,
    required String? checkOutDesc,
  }) {
    if (!isDateValid()) {
      return "Date must be today or yesterday";
    }

    if (type.isEmpty) return "Please select type";

    if (type == "Check In") {
      if ((checkInTime ?? "").isEmpty ||
          (checkInLoc ?? "").isEmpty ||
          (checkInDesc ?? "").isEmpty ||
          checkInProof == null) {
        return "Please fill all Check In fields";
      }
    }

    if (type == "Check Out") {
      if ((checkOutTime ?? "").isEmpty ||
          (checkOutLoc ?? "").isEmpty ||
          (checkOutDesc ?? "").isEmpty ||
          checkOutProof == null) {
        return "Please fill all Check Out fields";
      }
    }

    if (type == "Check In/Out") {
      if ((checkInTime ?? "").isEmpty ||
          (checkInLoc ?? "").isEmpty ||
          (checkInDesc ?? "").isEmpty ||
          checkInProof == null ||
          (checkOutTime ?? "").isEmpty ||
          (checkOutLoc ?? "").isEmpty ||
          (checkOutDesc ?? "").isEmpty ||
          checkOutProof == null) {
        return "Please fill all Check In & Check Out fields";
      }
    }

    return null; //  everything ok
  }
  CommonResponse? _RejectResponse;
  CommonResponse? get RejectResponse => _RejectResponse;


  /// Fetch attendance request list with filters
  Future<void> fetchAttendanceRequests(BuildContext context, mode,
      {String? type, String? dateRange, DateTimeRange? customRange}) async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();

    try {
      final provider = Provider.of<HomescreenNotifier>(context, listen: false);

      // Update filter states if provided
      if (type != null) _selectedType = type;
      if (dateRange != null) _selectedDateRange = dateRange;
      if (customRange != null) _customDateRange = customRange;

      // Calculate date range based on selection
      final dateParams = _getDateRangeParams(_selectedDateRange, _customDateRange);

      // Convert "All" type to empty string for API
      final apiType = _selectedType == "All" ? "" : _selectedType;

      final result = await ApiCalling.attendanceRequestListAPI(
        provider.empId,
        provider.session,
        apiType,
        dateParams['from']!,
        dateParams['to']!,
        mode
      );

      debugPrint('Fetching attendance from: ${dateParams['from']} to: ${dateParams['to']}');

      if (result != null) {
        _response = result;
        if (_response?.requestList == null || _response!.requestList!.isEmpty) {
          _errorMessage = "No attendance records found!";
        }
      } else {
        _errorMessage = "No data found!";
      }
    } catch (e) {
      _errorMessage = "Error: $e";
      debugPrint('Error fetching attendance: $e');
    }

    _isLoading = false;
    notifyListeners();
  }

  /// --- Add Attendance Request ---
  Future<void> addAttendanceRequest(
      BuildContext context, {
        required String process,
        required String type,
        required String loc,
        required String checkDate,
        String? checkInTime,
        String? checkInLoc,
        File? checkInProof,
        String? checkOutTime,
        String? checkOutLoc,
        File? checkOutProof,
        String? note,
      }) async {
    _isSubmitting = true;
    _errorMessage = null;
    _addResponse = null;
    notifyListeners();

    try {
      final homeProvider = Provider.of<HomescreenNotifier>(context, listen: false);

      final result = await ApiCalling.addAttendanceRequestAPI(
        sessionId: homeProvider.session,
        empId: homeProvider.empId,
        process: process,
        type: type,
        loc: loc,
        checkDate: checkDate,
        checkInTime: checkInTime,
        checkInLoc: checkInLoc,
        checkInProof: checkInProof,
        checkOutTime: checkOutTime,
        checkOutLoc: checkOutLoc,
        checkOutProof: checkOutProof,
        note: note,
      );

      if (result != null) {
        _addResponse = result;
        if (result.error != null && result.error!.isNotEmpty) {
          _errorMessage = result.error;
        } else {
          _addResponse = result;
        }
      } else {
        _errorMessage = "Failed to submit request!";
      }
    } catch (e) {
      _errorMessage = "Error submitting request: $e";
    }

    _isSubmitting = false;
    notifyListeners();
  }

  Future<void> rejectApproveAttendanceRequest({
    required String session,
    required String empId,
    required String mode,
    required String type,
    required String remarks,
    required String id,
  }) async {
    _isSubmitting = true;
    _errorMessage = null;
    _RejectResponse = null;
    notifyListeners();

    try {
      final result = await ApiCalling.attendanceRequestApproveRejectAPI(
        session,
        empId,
        mode,
        type,
        remarks,
        id,
      );
      print("*********************************object");

      if (result != null) {
        _RejectResponse = result;
        if (result.error != null && result.error!.isNotEmpty) {
          _errorMessage = result.error;
        } else {
          debugPrint("Attendance request $type successfully.");
        }
      } else {
        _errorMessage = "Failed to process attendance request!";
      }
    } catch (e) {
      _errorMessage = "Error processing attendance request: $e";
    }

    _isSubmitting = false;
    notifyListeners();
  }


  /// Apply filters coming from bottom sheet
  void updateFiltersFromSheet(
      mode,
      BuildContext context, {
        required String type,
        required String selectedValue,
        DateTimeRange? customRange,
      }) {
    _selectedType = type;
    _selectedDateRange = selectedValue;
    _customDateRange = customRange;

    fetchAttendanceRequests(
      context,
      mode,
      type: _selectedType,
      dateRange: _selectedDateRange,
      customRange: _customDateRange,
    );
  }

  /// Set type filter and refresh data
  void setTypeFilter(BuildContext context, String type, mode) {
    _selectedType = type;
    fetchAttendanceRequests(context, mode);
  }

  /// Set date range filter and refresh data
  void setDateRangeFilter(BuildContext context, String dateRange, mode,
      {DateTimeRange? customRange}) {
    _selectedDateRange = dateRange;
    if (customRange != null) {
      _customDateRange = customRange;
      fromDateController.text = _formatDate(customRange.start);
      toDateController.text = _formatDate(customRange.end);
    }
    fetchAttendanceRequests(context, mode);
  }

  /// Clear all filters and refresh data
  void clearFilters(BuildContext context, mode) {
    _selectedType = "All";
    _selectedDateRange = "This Month";
    _customDateRange = null;
    fromDateController.clear();
    toDateController.clear();
    fetchAttendanceRequests(context, mode);
  }

  /// Reset form and data
  void resetForm(BuildContext context, mode) {
    _response = null;
    _errorMessage = null;
    clearFilters(context, mode);
    notifyListeners();
  }

  /// Get date range parameters for API
  Map<String, String> _getDateRangeParams(String dateRange, DateTimeRange? customRange) {
    final now = DateTime.now();
    final formatter = DateFormat("dd MMM yyyy");
    late DateTime from;
    late DateTime to;

    switch (dateRange) {
      case "All":
        from = DateTime(now.year - 1);
        to = now;
        break;
      case "Today":
        from = now;
        to = now;
        break;
      case "Yesterday":
        from = now.subtract(const Duration(days: 1));
        to = now.subtract(const Duration(days: 1));
        break;
      case "This Month":
        from = DateTime(now.year, now.month, 1);
        to = DateTime(now.year, now.month + 1, 0);
        break;
      case "Past 7 days":
        from = now.subtract(const Duration(days: 6));
        to = now;
        break;
      case "Last Month":
        from = DateTime(now.year, now.month - 1, 1);
        to = DateTime(now.year, now.month, 0);
        break;
      case "Custom":
        if (customRange != null) {
          from = customRange.start;
          to = customRange.end;
        } else {
          from = now.subtract(const Duration(days: 30));
          to = now;
        }
        break;
      default:
        from = now;
        to = now;
    }

    return {
      "from": formatter.format(from),
      "to": formatter.format(to),
    };
  }

  /// Format date for display
  String _formatDate(DateTime date) {
    return DateFormat("dd MMM yyyy").format(date);
  }

  /// Apply filters and refresh data
  void applyFilters(BuildContext context, mode) {
    fetchAttendanceRequests(
      context,
      mode,
      type: _selectedType,
      dateRange: _selectedDateRange,
      customRange: _customDateRange,
    );
  }

  ///  Set Selected Date
  void setSelectedDate(DateTime date) {
    _selectedDate = date;
    dateController.text = DateFormat("dd MMM yyyy").format(date);
    notifyListeners();
  }

  /// Show Cupertino Date Picker
  void showDatePickerDialog(BuildContext context) {
    DateTime now = DateTime.now();
    DateTime today = DateTime(now.year, now.month, now.day);

    // Normalize selected date (strip time)
    if (_selectedDate == null) {
      setSelectedDate(today);
    } else {
      _selectedDate = DateTime(
        _selectedDate!.year,
        _selectedDate!.month,
        _selectedDate!.day,
      );
    }
    // Always reset before showing
    _selectedDate = today;
    setSelectedDate(today);

    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) => Container(
        height: 250,
        padding: const EdgeInsets.only(top: 6.0),
        margin: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        color: CupertinoColors.systemBackground.resolveFrom(context),
        child: SafeArea(
          top: false,
          child: Column(
            children: [
              // Cancel + Done Buttons
              SizedBox(
                height: 55,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    CupertinoButton(
                      child: Text(
                        'Cancel',
                        style: TextStyle(
                          fontFamily: "JakartaMedium",
                          color: AppColors.app_blue,
                        ),
                      ),
                      onPressed: () => Navigator.pop(context),
                    ),
                    CupertinoButton(
                      child: Text(
                        'Done',
                        style: TextStyle(
                          fontFamily: "JakartaMedium",
                          color: AppColors.app_blue,
                        ),
                      ),
                      onPressed: () {
                        // Ensure we save only date without time
                        final pickedDate = _selectedDate ?? today;
                        setSelectedDate(DateTime(
                          pickedDate.year,
                          pickedDate.month,
                          pickedDate.day,
                        ));
                        Navigator.pop(context);
                      },
                    ),
                  ],
                ),
              ),
              // Cupertino Date Picker
              Expanded(
                child: CupertinoDatePicker(
                  dateOrder: DatePickerDateOrder.dmy,
                  initialDateTime: _selectedDate ?? today,
                  minimumDate: today.subtract(const Duration(days: 2)),
                  maximumDate: today,
                  mode: CupertinoDatePickerMode.date,
                  use24hFormat: true,
                  showDayOfWeek: true,
                  onDateTimeChanged: (DateTime newDate) {
                    // Always normalize new date to midnight
                    setSelectedDate(DateTime(newDate.year, newDate.month, newDate.day));
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

}
