import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:generp/Models/ordersModels/commonResponse.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

import '../../Models/hrmModels/leaveApplicationLIstResponse.dart';
import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart';

class LeaveApplicationListProvider extends ChangeNotifier {
  leaveApplicationLIstResponse? _response;
  bool _isLoading = false;
  String? _errorMessage;

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

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

  String get selectedStatus => _selectedStatus;
  String get selectedDateRange => _selectedDateRange;
  DateTimeRange? get customDateRange => _customDateRange;

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

  // Controllers for Add Leave form
  final TextEditingController fromDateField = TextEditingController();
  final TextEditingController toDateField = TextEditingController();
  final TextEditingController fromTimeField = TextEditingController();
  final TextEditingController toTimeField = TextEditingController();
  final TextEditingController reasonController = TextEditingController();

  // Status options for filter
  final List<String> statusOptions = [
    "All",
    "Requested",
    "Approved",
    "Rejected",
  ];

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

  // Loading state for Add Leave
  bool _isSubmitting = false;
  bool get isSubmitting => _isSubmitting;

  CommonResponse? _addResponse;
  CommonResponse? get addResponse => _addResponse;

  DateTime? _selectedDate;
  DateTime? get selectedDate => _selectedDate;

  /// Fetch leave application list with filters
  Future<void> fetchLeaveApplications(
    BuildContext context,
    mode, {
    String? status,
    String? dateRange,
    DateTimeRange? customRange,
  }) async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();

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

      final filterStatus = status ?? _selectedStatus;
      final filterDateRange = dateRange ?? _selectedDateRange;
      final filterCustomRange = customRange ?? _customDateRange;

      final dateParams = _getDateRangeParams(
        filterDateRange,
        filterCustomRange,
      );

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

      debugPrint(
        'Fetching leave applications from: ${dateParams['from']} to: ${dateParams['to']}',
      );

      if (result != null) {
        _response = result;

        if (filterStatus != "All" && _response?.requestList != null) {
          _response!.requestList =
              _response!.requestList!
                  .where(
                    (item) =>
                        item.status?.toLowerCase() ==
                        filterStatus.toLowerCase(),
                  )
                  .toList();
        }

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

    _isLoading = false;
    notifyListeners();
  }

  /// --- Add Leave Request ---
  Future<void> addLeaveRequest(
    BuildContext context, {
    required String fromDate,
    required String fromTime,
    required String toDate,
    required String toTime,
    required String leaveType,
    required String reason,
  }) async {
    _isSubmitting = true;
    _errorMessage = null;
    _addResponse = null;
    notifyListeners();

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

      final result = await ApiCalling.leaveRequestAddAPI(
        homeProvider.session,
        homeProvider.empId,
        fromDate,
        fromTime,
        toDate,
        toTime,
        leaveType,
        reason,
      );

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

    _isSubmitting = false;
    notifyListeners();
  }

  /// Set status filter
  void setStatusFilter(String status) {
    _selectedStatus = status;
    notifyListeners();
  }

  /// Set date range filter
  void setDateRangeFilter(String dateRange, {DateTimeRange? customRange}) {
    _selectedDateRange = dateRange;
    if (customRange != null) {
      _customDateRange = customRange;
      fromDateController.text = _formatDate(customRange.start);
      toDateController.text = _formatDate(customRange.end);
    }
    notifyListeners();
  }

  /// Clear all filters
  void clearFilters() {
    _selectedStatus = "All";
    _selectedDateRange = "This Month";
    _customDateRange = null;
    fromDateController.clear();
    toDateController.clear();
    notifyListeners();
  }

  /// Reset form and data
  void resetForm() {
    _response = null;
    _errorMessage = null;
    clearFilters();
    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
  String _formatDate(DateTime date) {
    return DateFormat("dd MMM yyyy").format(date);
  }

  /// Show Cupertino DatePicker for leave form
  void showDatePickerDialog(BuildContext context, {bool isFromDate = true}) {
    DateTime now = DateTime.now();
    DateTime? currentDate = now;

    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: [
                  SizedBox(
                    height: 55,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        CupertinoButton(
                          child: const Text(
                            "Cancel",
                            style: TextStyle(color: Colors.blue),
                          ),
                          onPressed: () => Navigator.pop(context),
                        ),
                        CupertinoButton(
                          child: const Text(
                            "Done",
                            style: TextStyle(color: Colors.blue),
                          ),
                          onPressed: () {
                            if (isFromDate) {
                              fromDateField.text = _formatDate(
                                currentDate ?? now,
                              );
                            } else {
                              toDateField.text = _formatDate(
                                currentDate ?? now,
                              );
                            }
                            Navigator.pop(context);
                          },
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    child: CupertinoDatePicker(
                      dateOrder: DatePickerDateOrder.dmy,
                      initialDateTime: now,
                      minimumDate: DateTime(now.year, now.month, now.day),
                      maximumDate: DateTime(now.year + 5), // limit
                      mode: CupertinoDatePickerMode.date,
                      onDateTimeChanged: (DateTime newDate) {
                        currentDate = newDate;
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
    );
  }

  /// Apply filters
  void applyFilters(BuildContext context, mode) {
    fetchLeaveApplications(
      context,
      mode,
      status: _selectedStatus,
      dateRange: _selectedDateRange,
      customRange: _customDateRange,
    );
  }

  /// Export
  List<List<String>> prepareExportData() {
    final headers = [
      'ID',
      'Applied Date',
      'From Date',
      'To Date',
      'Leave Type',
      'Status',
      'Reason',
    ];

    if (_response?.requestList == null) {
      return [headers];
    }

    final rows =
        _response!.requestList!
            .map(
              (item) => [
                item.id ?? '',
                item.appliedDate ?? '',
                item.fromPeriod ?? '',
                item.toPeriod ?? '',
                '', // leave type if available
                item.status ?? '',
                '', // reason if available
              ],
            )
            .toList();

    return [headers, ...rows];
  }

  /// Set selected single date (if needed)
  void setSelectedDate(DateTime date) {
    _selectedDate = date;
    notifyListeners();
  }
}
