import 'dart:async';
import 'package:flutter/foundation.dart';
import '../models/price_data.dart';
import '../services/websocket_service.dart';
import '../services/api_service.dart';
import '../services/storage_service.dart';
import '../services/notification_service.dart';

class PriceProvider with ChangeNotifier {
  final WebSocketService _wsService = WebSocketService();
  final ApiService _apiService = ApiService();
  final StorageService _storageService = StorageService();
  final NotificationService _notificationService = NotificationService();

  LatestPrice? _latestPrice;
  HistoryData? _historyData;
  String _connectionStatus = 'Disconnected';
  List<PriceAlert> _alerts = [];
  double? _customAuecAmount;
  String _selectedRange = '7d';
  bool _isLoading = false;
  bool _isHistoryLoading = false;

  LatestPrice? get latestPrice => _latestPrice;
  HistoryData? get historyData => _historyData;
  String get connectionStatus => _connectionStatus;
  List<PriceAlert> get alerts => _alerts;
  double? get customAuecAmount => _customAuecAmount;
  String get selectedRange => _selectedRange;
  bool get isLoading => _isLoading;
  bool get isHistoryLoading => _isHistoryLoading;

  PriceProvider() {
    _initialize();
  }

  Timer? _pollTimer;

  void _initialize() {
    // Load saved data
    _loadAlerts();
    _loadCustomAuecAmount();

    // Connect WebSocket (currently disabled)
    _wsService.connect();

    // Listen to WebSocket streams
    _wsService.latestPriceStream.listen((price) {
      _latestPrice = price;
      _checkAlerts(price);
      notifyListeners();
    });

    _wsService.connectionStatusStream.listen((status) {
      _connectionStatus = status;
      notifyListeners();
    });

    // Fetch initial data
    fetchInitialData();
    
    // Start polling for updates every 5 minutes as backup to WebSocket
    _startPolling();
  }

  void _startPolling() {
    _pollTimer = Timer.periodic(const Duration(minutes: 5), (timer) {
      fetchInitialData();
    });
  }

  Future<void> fetchInitialData() async {
    final latest = await _apiService.fetchLatestPrice();
    if (latest != null) {
      _latestPrice = latest;
      notifyListeners();
    }
    await fetchHistory(_selectedRange);
  }

  Future<void> fetchHistory(String range) async {
    _isHistoryLoading = true;
    _selectedRange = range;
    notifyListeners();
    
    try {
      final history = await _apiService.fetchHistory(range);
      if (history != null) {
        _historyData = history;
      }
      _wsService.requestHistory(range);
    } catch (e) {
      if (kDebugMode) {
        print('Error fetching history: $e');
      }
    } finally {
      _isHistoryLoading = false;
      notifyListeners();
    }
  }

  Future<void> _loadAlerts() async {
    _alerts = await _storageService.getAlerts();
    notifyListeners();
  }

  Future<void> _loadCustomAuecAmount() async {
    _customAuecAmount = await _storageService.getCustomAuecAmount();
    notifyListeners();
  }

  Future<void> addAlert(double auecAmount, double maxPrice) async {
    final alert = PriceAlert(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      auecAmount: auecAmount,
      maxPrice: maxPrice,
      enabled: true,
    );
    await _storageService.addAlert(alert);
    await _loadAlerts();
  }

  Future<void> toggleAlert(String id) async {
    final alert = _alerts.firstWhere((a) => a.id == id);
    final updated = alert.copyWith(enabled: !alert.enabled);
    await _storageService.updateAlert(updated);
    await _loadAlerts();
  }

  Future<void> deleteAlert(String id) async {
    await _storageService.deleteAlert(id);
    await _loadAlerts();
  }

  Future<void> setCustomAuecAmount(double amount) async {
    await _storageService.setCustomAuecAmount(amount);
    _customAuecAmount = amount;
    notifyListeners();
  }

  void _checkAlerts(LatestPrice price) {
    for (final alert in _alerts) {
      if (!alert.enabled) continue;

      final matchingSeller = price.allPrices.firstWhere(
        (p) {
          final totalPrice = (alert.auecAmount / 1000000) * p.pricePerMillion;
          return totalPrice <= alert.maxPrice;
        },
        orElse: () => price.allPrices.first,
      );

      final totalPrice = (alert.auecAmount / 1000000) * matchingSeller.pricePerMillion;
      if (totalPrice <= alert.maxPrice) {
        // Trigger notification
        _notificationService.showPriceAlert(
          title: 'Price Alert Triggered!',
          body: '${(alert.auecAmount / 1000000000).toStringAsFixed(1)}B AUEC available for \$${totalPrice.toStringAsFixed(2)} from ${matchingSeller.sellerName}',
          auecAmount: alert.auecAmount,
          price: totalPrice,
          seller: matchingSeller.sellerName,
        );
        
        // Disable alert
        toggleAlert(alert.id);
      }
    }
  }

  @override
  void dispose() {
    _pollTimer?.cancel();
    _wsService.dispose();
    super.dispose();
  }
}
