import 'dart:async';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:socket_io_client/socket_io_client.dart' as io;
import '../../features/notifications/domain/entities/app_notification.dart';

/// Service that connects to the comm-service Socket.IO gateway
/// and displays local notifications for real-time push events.
class NotificationService {
  final String baseUrl;
  final String? accessToken;
  final FlutterLocalNotificationsPlugin _localNotifications;

  io.Socket? _socket;
  String? _tenantId;
  final _controller = StreamController<AppNotification>.broadcast();
  int _notificationId = 0;

  NotificationService({
    required this.baseUrl,
    this.accessToken,
    required FlutterLocalNotificationsPlugin localNotifications,
  }) : _localNotifications = localNotifications;

  /// Stream of incoming notifications.
  Stream<AppNotification> get notifications => _controller.stream;

  /// Connect to the comm-service WebSocket gateway.
  void connect(String tenantId) {
    _tenantId = tenantId;
    disconnect();

    _socket = io.io(
      '$baseUrl/ws/comm',
      io.OptionBuilder()
          .setTransports(['websocket'])
          .enableAutoConnect()
          .setExtraHeaders(
            accessToken != null
                ? {'Authorization': 'Bearer $accessToken'}
                : {},
          )
          .build(),
    );

    _socket!.onConnect((_) {
      // Join the tenant room
      _socket!.emit('join', {'room': 'tenant:$_tenantId'});
    });

    // Listen for notification events
    _socket!.on('notification', (data) {
      if (data is Map<String, dynamic>) {
        final notification = AppNotification.fromJson(data);
        _controller.add(notification);
        _showLocalNotification(notification);
      }
    });

    _socket!.onDisconnect((_) {});
    _socket!.onConnectError((_) {});
  }

  /// Disconnect from the WebSocket gateway.
  void disconnect() {
    _socket?.dispose();
    _socket = null;
  }

  /// Show a local notification on the device.
  Future<void> _showLocalNotification(AppNotification notification) async {
    const androidDetails = AndroidNotificationDetails(
      'it0_notifications',
      '运维通知',
      channelDescription: '我智能体 运维告警和通知',
      importance: Importance.high,
      priority: Priority.high,
    );

    const details = NotificationDetails(android: androidDetails);

    await _localNotifications.show(
      _notificationId++,
      notification.title,
      notification.body,
      details,
      payload: notification.actionRoute,
    );
  }

  /// Clean up resources.
  void dispose() {
    disconnect();
    _controller.close();
  }
}
