import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/dinosaur.dart';

class DinoProvider extends ChangeNotifier {
  List<Dinosaur> _allDinos = [];
  List<Dinosaur> _filteredDinos = [];
  Set<String> _favoriteNames = {};

  bool _isMetric = true;
  bool _isDarkMode = false;
  Dinosaur? _dinoOfTheDay;
  String _searchQuery = "";
  String _selectedDiet = "All";
  String _selectedClassification = "All";

  List<Dinosaur> get dinos => _filteredDinos;
  bool get isMetric => _isMetric;
  bool get isDarkMode => _isDarkMode;
  Dinosaur? get dinoOfTheDay => _dinoOfTheDay;
  String get selectedDiet => _selectedDiet;
  String get selectedClassification => _selectedClassification;

  List<String> get classifications {
    final types = _allDinos.map((d) => d.classification).toSet().toList();
    types.sort();
    return ["All", ...types];
  }

  bool isFavorite(String name) => _favoriteNames.contains(name);

  List<Dinosaur> getRelated(Dinosaur current) {
    return _allDinos.where((d) => d.family == current.family && d.name != current.name).toList();
  }

  Future<void> loadData() async {
    try {
      final String response = await rootBundle.loadString('assets/dinosaurs.json');
      final List<dynamic> data = json.decode(response);
      _allDinos = data.map((json) => Dinosaur.fromJson(json)).toList();

      if (_allDinos.isNotEmpty) {
        int dayIndex = DateTime.now().difference(DateTime(2024, 1, 1)).inDays;
        _dinoOfTheDay = _allDinos[dayIndex % _allDinos.length];
      }

      final prefs = await SharedPreferences.getInstance();
      _isMetric = prefs.getBool('isMetric') ?? true;
      _isDarkMode = prefs.getBool('isDarkMode') ?? false;
      _favoriteNames = (prefs.getStringList('favorites') ?? []).toSet();
      _applyFilters();
    } catch (e) {
      debugPrint("Error loading data: $e");
    }
  }

  void toggleUnits() async {
    _isMetric = !_isMetric;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('isMetric', _isMetric);
    notifyListeners();
  }

  void toggleTheme() async {
    _isDarkMode = !_isDarkMode;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('isDarkMode', _isDarkMode);
    notifyListeners();
  }

  String formatWeight(double kg) => _isMetric ? "${kg.toInt()} kg" : "${(kg * 2.204).toInt()} lbs";
  String formatLength(double m) => _isMetric ? "$m m" : "${(m * 3.28).toStringAsFixed(1)} ft";

  void toggleFavorite(String name) async {
    if (_favoriteNames.contains(name)) _favoriteNames.remove(name);
    else _favoriteNames.add(name);
    final prefs = await SharedPreferences.getInstance();
    await prefs.setStringList('favorites', _favoriteNames.toList());
    notifyListeners();
  }

  void updateSearch(String q) { _searchQuery = q; _applyFilters(); }
  void updateDietFilter(String d) { _selectedDiet = d; _applyFilters(); }
  void updateClassificationFilter(String c) { _selectedClassification = c; _applyFilters(); }

  void _applyFilters() {
    _filteredDinos = _allDinos.where((dino) {
      final matchesSearch = dino.name.toLowerCase().contains(_searchQuery.toLowerCase());
      final matchesDiet = _selectedDiet == "All" || dino.dietType == _selectedDiet;
      final matchesClass = _selectedClassification == "All" || dino.classification == _selectedClassification;
      return matchesSearch && matchesDiet && matchesClass;
    }).toList();
    notifyListeners();
  }
}