import 'dart:async'; import 'package:flutter/material.dart'; import '../data/models/coin.dart'; import '../data/models/order_book.dart'; import '../data/services/market_service.dart'; import '../data/services/trade_service.dart'; /// 交易頁狀態管理 — 輪詢價格 + 訂單簿 class TradeProvider extends ChangeNotifier { final MarketService _marketService; // ignore: unused_field final TradeService _tradeService; TradeProvider(this._marketService, this._tradeService); Coin? _selectedCoin; OrderBookDepth _depth = const OrderBookDepth(asks: [], bids: [], spread: 0, spreadPercent: 0); bool _isLoadingDepth = false; String? _error; Timer? _pollTimer; static const _pollInterval = Duration(seconds: 5); Coin? get selectedCoin => _selectedCoin; OrderBookDepth get depth => _depth; bool get isLoadingDepth => _isLoadingDepth; String? get error => _error; /// 实时模拟价格(从 depth 轮询获取) double get currentPrice => _depth.currentPrice; double get change24h => _depth.change24h; double get high24h => _depth.high24h; double get low24h => _depth.low24h; double get volume24h => _depth.volume24h; /// 交易时段状态 String get tradingStatus => _depth.tradingStatus; double? get targetLow => _depth.targetLow; double? get targetHigh => _depth.targetHigh; double? get targetClose => _depth.targetClose; bool get isTradable => tradingStatus == 'trading'; void selectCoin(Coin coin) { if (_selectedCoin?.code == coin.code) return; _selectedCoin = coin; _depth = const OrderBookDepth(asks: [], bids: [], spread: 0, spreadPercent: 0); _error = null; notifyListeners(); startPolling(); } void clearSelection() { _selectedCoin = null; _depth = const OrderBookDepth(asks: [], bids: [], spread: 0, spreadPercent: 0); stopPolling(); notifyListeners(); } void startPolling() { stopPolling(); _fetchDepth(); _pollTimer = Timer.periodic(_pollInterval, (_) => _fetchDepth()); } void stopPolling() { _pollTimer?.cancel(); _pollTimer = null; } Future _fetchDepth() async { if (_selectedCoin == null) return; final response = await _marketService.getDepth(_selectedCoin!.code); if (!response.success || response.data == null) return; _depth = OrderBookDepth.fromJson(response.data!); notifyListeners(); } /// 刷新幣種價格(從 MarketProvider 的列表中找到最新價) void updateCoinPrice(Coin updatedCoin) { if (_selectedCoin?.code == updatedCoin.code) { _selectedCoin = updatedCoin; notifyListeners(); } } @override void dispose() { stopPolling(); super.dispose(); } }