import 'dart:async';

import 'package:flutter/foundation.dart';

import 'package:pshared/models/auto_refresh_mode.dart';
import 'package:pshared/models/payment/quote/status_type.dart';
import 'package:pshared/provider/payment/quotation/quotation.dart';


class QuotationController extends ChangeNotifier {
  QuotationProvider? _quotation;
  Timer? _ticker;

  void update(QuotationProvider quotation) {
    if (identical(_quotation, quotation)) return;
    _quotation?.removeListener(_handleQuotationChanged);
    _quotation = quotation;
    _quotation?.addListener(_handleQuotationChanged);
    _handleQuotationChanged();
  }

  bool get isLoading => _quotation?.isLoading ?? false;
  Exception? get error => _quotation?.error;
  bool get canRefresh => _quotation?.canRefresh ?? false;
  bool get isReady => _quotation?.isReady ?? false;
  AutoRefreshMode get autoRefreshMode =>
      _quotation?.autoRefreshMode ?? AutoRefreshMode.on;

  DateTime? get quoteExpiresAt => _quotation?.quoteExpiresAt;

  Duration? get timeLeft {
    final expiresAt = quoteExpiresAt;
    if (expiresAt == null) return null;
    return expiresAt.difference(DateTime.now().toUtc());
  }

  bool get isExpired {
    final remaining = timeLeft;
    if (remaining == null) return false;
    return remaining <= Duration.zero;
  }

  QuoteStatusType get quoteStatus {
    if (isLoading) return QuoteStatusType.loading;
    if (error != null) return QuoteStatusType.error;
    if (_quotation?.quotation == null) return QuoteStatusType.missing;
    if (isExpired) return QuoteStatusType.expired;
    return QuoteStatusType.active;
  }

  bool get hasLiveQuote => isReady && _quotation?.quotation != null && !isExpired;

  void setAutoRefreshMode(AutoRefreshMode mode) {
    _quotation?.setAutoRefreshMode(mode);
  }

  void refreshQuotation() {
    _quotation?.refreshQuotation();
  }

  void _handleQuotationChanged() {
    _syncTicker();
    notifyListeners();
  }

  void _syncTicker() {
    final expiresAt = quoteExpiresAt;
    if (expiresAt == null) {
      _stopTicker();
      return;
    }

    final remaining = expiresAt.difference(DateTime.now().toUtc());
    if (remaining <= Duration.zero) {
      _stopTicker();
      return;
    }

    _ticker ??= Timer.periodic(const Duration(seconds: 1), (_) {
      final expiresAt = quoteExpiresAt;
      if (expiresAt == null) {
        _stopTicker();
        return;
      }
      final remaining = expiresAt.difference(DateTime.now().toUtc());
      if (remaining <= Duration.zero) {
        _stopTicker();
      }
      notifyListeners();
    });
  }

  void _stopTicker() {
    _ticker?.cancel();
    _ticker = null;
  }

  @override
  void dispose() {
    _quotation?.removeListener(_handleQuotationChanged);
    _stopTicker();
    super.dispose();
  }
}
