import 'dart:convert';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/category.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/monthly/monthly_model.dart';
import 'package:didvan/providers/core.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class MonthlyListState extends CoreProvier {
  List<MonthlyItem> monthlyItems = [];
  List<MonthlyItem> _allMonthlyItems = [];
  String searchQuery = '';
  String? startDate;
  String? endDate;
  final List<CategoryData> selectedCats = [];
  List<CategoryData> categories = [];
  bool filtering = false;

  void initCategories() {
    categories = [
      CategoryData(
        id: 1,
        label: 'اقتصادی',
        asset: Assets.economicCategoryIcon,
      ),
      CategoryData(
        id: 2,
        label: 'سیاسی',
        asset: Assets.politicalCategoryIcon,
      ),
      CategoryData(
        id: 3,
        label: 'فناوری',
        asset: Assets.techCategoryIcon,
      ),
      CategoryData(
        id: 4,
        label: 'کسب و کار',
        asset: Assets.businessCategoryIcon,
      ),
      CategoryData(
        id: 5,
        label: 'زیست‌محیطی',
        asset: Assets.enviromentalCategoryIcon,
      ),
      CategoryData(
        id: 6,
        label: 'اجتماعی',
        asset: Assets.socialCategoryIcon,
      ),
    ];
  }

  bool get searching => searchQuery.isNotEmpty;

  Future<void> fetchMonthlyList() async {
    appState = AppState.busy;
    notifyListeners();

    try {
      final url = '${RequestHelper.baseUrl}/monthly';
      debugPrint('Fetching monthly list from: $url');

      final response = await http.get(
        Uri.parse(url),
        headers: {
          'Authorization': 'Bearer ${RequestService.token}',
          'accept': '*/*',
          'Content-Type': 'application/json; charset=UTF-8',
        },
      ).timeout(const Duration(seconds: 30));

      debugPrint('Response status code: ${response.statusCode}');

      if (response.statusCode == 200) {
        final jsonData = json.decode(response.body);
        debugPrint('Decoded JSON: $jsonData');

        final List<dynamic> resultList = jsonData['result'] as List;
        debugPrint('Found ${resultList.length} items');

        _allMonthlyItems =
            resultList.map((item) => MonthlyItem.fromJson(item)).toList();

        monthlyItems = _applyFilters(_allMonthlyItems);

        debugPrint(
            'Successfully parsed ${monthlyItems.length} monthly items after filters');
        appState = AppState.idle;
      } else {
        debugPrint('Request failed with status code: ${response.statusCode}');
        appState = AppState.failed;
      }
    } catch (e, stackTrace) {
      debugPrint('Error fetching monthly list: $e');
      debugPrint('Stack trace: $stackTrace');
      appState = AppState.failed;
    }
    notifyListeners();
  }

  void search(String query) {
    searchQuery = query;
    var filtered = _allMonthlyItems;

    if (query.isNotEmpty) {
      filtered = filtered
          .where((item) =>
              item.title.toLowerCase().contains(query.toLowerCase()) ||
              item.description.toLowerCase().contains(query.toLowerCase()))
          .toList();
    }

    monthlyItems = _applyFilters(filtered);
    notifyListeners();
  }

  Future<void> toggleLike(int id) async {
    try {
      final url = '${RequestHelper.baseUrl}/monthly/$id/like';
      debugPrint('Toggling like for monthly item: $url');

      final index = monthlyItems.indexWhere((item) => item.id == id);
      if (index != -1) {
        monthlyItems[index].isLiked = !monthlyItems[index].isLiked;
        notifyListeners();
      }

      final response = await http.post(
        Uri.parse(url),
        headers: {
          'Authorization': 'Bearer ${RequestService.token}',
          'accept': '*/*',
          'Content-Type': 'application/json; charset=UTF-8',
        },
      ).timeout(const Duration(seconds: 30));

      if (response.statusCode == 200) {
        debugPrint('Like toggled successfully');
      } else {
        debugPrint('Failed to toggle like: ${response.statusCode}');
        if (index != -1) {
          monthlyItems[index].isLiked = !monthlyItems[index].isLiked;
          notifyListeners();
        }
      }
    } catch (e) {
      debugPrint('Error toggling like: $e');
      final index = monthlyItems.indexWhere((item) => item.id == id);
      if (index != -1) {
        monthlyItems[index].isLiked = !monthlyItems[index].isLiked;
        notifyListeners();
      }
    }
  }

  Future<void> toggleBookmark(int id) async {
    try {
      final url = '${RequestHelper.baseUrl}/monthly/$id/mark';
      debugPrint('Toggling bookmark for monthly item: $url');

      final index = monthlyItems.indexWhere((item) => item.id == id);
      if (index != -1) {
        monthlyItems[index].isBookmarked = !monthlyItems[index].isBookmarked;
        notifyListeners();
      }

      final response = await http.post(
        Uri.parse(url),
        headers: {
          'Authorization': 'Bearer ${RequestService.token}',
          'accept': '*/*',
          'Content-Type': 'application/json; charset=UTF-8',
        },
      ).timeout(const Duration(seconds: 30));

      if (response.statusCode == 200) {
        debugPrint('Bookmark toggled successfully');
      } else {
        debugPrint('Failed to toggle bookmark: ${response.statusCode}');
        if (index != -1) {
          monthlyItems[index].isBookmarked = !monthlyItems[index].isBookmarked;
          notifyListeners();
        }
      }
    } catch (e) {
      debugPrint('Error toggling bookmark: $e');
      final index = monthlyItems.indexWhere((item) => item.id == id);
      if (index != -1) {
        monthlyItems[index].isBookmarked = !monthlyItems[index].isBookmarked;
        notifyListeners();
      }
    }
  }

  void resetFilters([bool notify = true]) {
    startDate = null;
    endDate = null;
    selectedCats.clear();
    filtering = false;
    if (notify) {
      fetchMonthlyList();
    }
  }

  List<MonthlyItem> _applyFilters(List<MonthlyItem> items) {
    var filtered = items;

    if (startDate != null || endDate != null) {
      filtered = filtered.where((item) {
        final itemDate = DateTime.parse(item.publishedAt);

        if (startDate != null) {
          final start = DateTime.parse(startDate!);
          if (itemDate.isBefore(start)) return false;
        }

        if (endDate != null) {
          final end = DateTime.parse(endDate!).add(const Duration(days: 1));
          if (itemDate.isAfter(end)) return false;
        }

        return true;
      }).toList();
    }

    if (selectedCats.isNotEmpty) {
      filtered = filtered.where((item) {
        return item.tags
            .any((tag) => selectedCats.any((cat) => cat.id == tag.id));
      }).toList();
    }

    return filtered;
  }
}
