import 'dart:async';
import 'package:autosos_flutter/api/order_api.dart';
import 'package:autosos_flutter/config/constant.dart';
import 'package:autosos_flutter/model/order.dart';
import 'package:autosos_flutter/model/payment.dart';
import 'package:autosos_flutter/service/audio_service.dart';
import 'package:autosos_flutter/service/location_service.dart';
import 'package:flutter/foundation.dart';

/// 订单状态机 + 业务编排服务（对应 Android 订单状态机）
class OrderService {
  static final OrderService instance = OrderService._();
  OrderService._();

  Order? _current;
  Order? get currentOrder => _current;

  /// 状态变化回调
  final _stateController = StreamController<OrderStateEvent>.broadcast();
  Stream<OrderStateEvent> get stateStream => _stateController.stream;

  /// 救援中（conducting）→ 上报当前位置的轨迹点
  Timer? _trackUploadTimer;

  /// 设置当前订单
  void setCurrent(Order? order) {
    _current = order;
    if (order != null) {
      Constant.isService = order.status == OrderStatus.conducting;
      _stateController.add(OrderStateEvent.updated(order));
    }
  }

  /// 接单
  Future<Order> grab(int orderId) async {
    final resp = await OrderApi.instance.grabOrder(orderId);
    if (!resp.isSuccess) throw Exception(resp.message ?? '接单失败');
    final order = resp.data!;
    setCurrent(order);
    return order;
  }

  /// 到达现场
  Future<void> arrive({double? lat, double? lng}) async {
    if (_current == null) throw Exception('当前无进行中订单');
    final loc = LocationService.instance.last;
    final r = await OrderApi.instance.arriveScene(
      _current!.id,
      lat: lat ?? (loc?['latitude'] as num?)?.toDouble(),
      lng: lng ?? (loc?['longitude'] as num?)?.toDouble(),
    );
    if (!r.isSuccess) throw Exception(r.message ?? '上报到达失败');
    final updated = _current!.copyWith(
      status: OrderStatus.conducting,
      arrivedAt: DateTime.now(),
    );
    setCurrent(updated);
    _startTrack();
  }

  /// 完成订单
  Future<dynamic> complete({
    required List<AmountItem> amountItems,
    String? remark,
  }) async {
    if (_current == null) throw Exception('当前无订单');
    final r = await OrderApi.instance.completeOrder(
      orderId: _current!.id,
      amountItems: amountItems,
      remark: remark,
    );
    if (!r.isSuccess) throw Exception(r.message ?? '完成订单失败');
    _stopTrack();
    setCurrent(_current!.copyWith(
      status: OrderStatus.completed,
      completedAt: DateTime.now(),
    ));
    return r.data;
  }

  /// 取消订单
  Future<void> cancel() async {
    if (_current == null) return;
    _stopTrack();
    setCurrent(_current!.copyWith(status: OrderStatus.cancelled));
  }

  /// 启动轨迹上传
  void _startTrack() {
    _trackUploadTimer?.cancel();
    _trackUploadTimer = Timer.periodic(const Duration(seconds: 10), (_) async {
      if (_current == null) return;
      final loc = LocationService.instance.last;
      if (loc == null) return;
      try {
        await OrderApi.instance.uploadTrackPoints(_current!.id, [
          {
            'lat': (loc['latitude'] as num?)?.toDouble() ?? 0,
            'lng': (loc['longitude'] as num?)?.toDouble() ?? 0,
            'time': DateTime.now().toIso8601String(),
            'speed': (loc['speed'] as num?)?.toDouble() ?? 0,
            'bearing': (loc['bearing'] as num?)?.toDouble() ?? 0,
          }
        ]);
      } catch (e) {
        debugPrint('Track upload failed: $e');
      }
    });
  }

  /// 停止轨迹上传
  void _stopTrack() {
    _trackUploadTimer?.cancel();
    _trackUploadTimer = null;
  }

  /// 收到新订单推送时触发本地语音提醒
  Future<void> onPushNewOrder(Map<String, dynamic> payload) async {
    final type = (payload['type'] as num?)?.toInt() ?? 0;
    if (type == Constant.NEW_ORDER_INSIDE) {
      AudioService.instance.newInsideOrder();
    } else if (type == Constant.NEW_ORDER_JIUJIU) {
      AudioService.instance.newJiuJiuOrder();
    }
  }

  void dispose() {
    _stopTrack();
    _stateController.close();
  }
}

/// 订单状态变化事件
class OrderStateEvent {
  final OrderStateEventType type;
  final Order? order;
  const OrderStateEvent(this.type, this.order);

  factory OrderStateEvent.updated(Order o) => OrderStateEvent(OrderStateEventType.updated, o);
}

enum OrderStateEventType { updated, completed, cancelled, paid }