import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.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();
  }
}
