import 'package:flutter/foundation.dart';
import '../network/api_client.dart';

/// 通知类型
enum NotificationType {
  system,
  activity,
  reward,
  upgrade,
  announcement,
}

/// 通知优先级
enum NotificationPriority {
  low,
  normal,
  high,
  urgent,
}

/// 通知项
class NotificationItem {
  final String id;
  final String title;
  final String content;
  final NotificationType type;
  final NotificationPriority priority;
  final String? imageUrl;
  final String? linkUrl;
  final DateTime? publishedAt;
  final bool isRead;
  final DateTime? readAt;

  NotificationItem({
    required this.id,
    required this.title,
    required this.content,
    required this.type,
    required this.priority,
    this.imageUrl,
    this.linkUrl,
    this.publishedAt,
    required this.isRead,
    this.readAt,
  });

  factory NotificationItem.fromJson(Map<String, dynamic> json) {
    return NotificationItem(
      id: json['id']?.toString() ?? '',
      title: json['title'] ?? '',
      content: json['content'] ?? json['body'] ?? '',
      type: _parseType(json['type']),
      priority: _parsePriority(json['priority']),
      imageUrl: json['imageUrl'],
      linkUrl: json['linkUrl'],
      publishedAt: json['publishedAt'] != null
          ? DateTime.tryParse(json['publishedAt'])
          : (json['createdAt'] != null ? DateTime.tryParse(json['createdAt']) : null),
      isRead: json['isRead'] ?? (json['status'] == 'READ'),
      readAt: json['readAt'] != null ? DateTime.tryParse(json['readAt']) : null,
    );
  }

  static NotificationType _parseType(String? type) {
    switch (type?.toUpperCase()) {
      case 'SYSTEM':
        return NotificationType.system;
      case 'ACTIVITY':
        return NotificationType.activity;
      case 'REWARD':
        return NotificationType.reward;
      case 'UPGRADE':
        return NotificationType.upgrade;
      case 'ANNOUNCEMENT':
        return NotificationType.announcement;
      default:
        return NotificationType.system;
    }
  }

  static NotificationPriority _parsePriority(String? priority) {
    switch (priority?.toUpperCase()) {
      case 'LOW':
        return NotificationPriority.low;
      case 'HIGH':
        return NotificationPriority.high;
      case 'URGENT':
        return NotificationPriority.urgent;
      default:
        return NotificationPriority.normal;
    }
  }
}

/// 通知列表响应
class NotificationListResponse {
  final List<NotificationItem> notifications;
  final int total;
  final int unreadCount;

  NotificationListResponse({
    required this.notifications,
    required this.total,
    required this.unreadCount,
  });

  factory NotificationListResponse.fromJson(Map<String, dynamic> json) {
    final data = json['data'] ?? json;
    final list = (data['notifications'] as List?)
            ?.map((e) => NotificationItem.fromJson(e as Map<String, dynamic>))
            .toList() ??
        (data['items'] as List?)
            ?.map((e) => NotificationItem.fromJson(e as Map<String, dynamic>))
            .toList() ??
        [];
    return NotificationListResponse(
      notifications: list,
      total: data['total'] ?? list.length,
      unreadCount: data['unreadCount'] ?? 0,
    );
  }
}

/// 通知服务
class NotificationService {
  final ApiClient _apiClient;

  NotificationService({ApiClient? apiClient})
      : _apiClient = apiClient ?? ApiClient.instance;

  /// 获取通知列表
  Future<NotificationListResponse> getNotifications({
    NotificationType? type,
    int limit = 50,
    int offset = 0,
  }) async {
    try {
      final queryParams = <String, dynamic>{
        'limit': limit,
        'offset': offset,
      };
      if (type != null) {
        queryParams['type'] = type.name.toUpperCase();
      }

      final response = await _apiClient.get(
        '/api/v1/notifications',
        queryParameters: queryParams,
      );

      return NotificationListResponse.fromJson(
        response.data is Map<String, dynamic> ? response.data : {},
      );
    } catch (e) {
      debugPrint('[NotificationService] 获取通知列表失败: $e');
      rethrow;
    }
  }

  /// 获取未读通知数量
  Future<int> getUnreadCount() async {
    try {
      final response = await _apiClient.get('/api/v1/notifications/unread-count');
      final data = response.data is Map<String, dynamic> ? response.data : {};
      return data['data']?['count'] ?? data['count'] ?? 0;
    } catch (e) {
      debugPrint('[NotificationService] 获取未读数量失败: $e');
      return 0;
    }
  }

  /// 标记通知为已读
  Future<bool> markAsRead(String notificationId) async {
    try {
      await _apiClient.put('/api/v1/notifications/$notificationId/read');
      return true;
    } catch (e) {
      debugPrint('[NotificationService] 标记已读失败: $e');
      return false;
    }
  }

  /// 获取公告列表
  Future<NotificationListResponse> getAnnouncements({
    int limit = 50,
    int offset = 0,
  }) async {
    try {
      final response = await _apiClient.get(
        '/api/v1/announcements',
        queryParameters: {'limit': limit, 'offset': offset},
      );

      return NotificationListResponse.fromJson(
        response.data is Map<String, dynamic> ? response.data : {},
      );
    } catch (e) {
      debugPrint('[NotificationService] 获取公告列表失败: $e');
      rethrow;
    }
  }

  /// 获取公告未读数
  Future<int> getAnnouncementUnreadCount() async {
    try {
      final response = await _apiClient.get('/api/v1/announcements/unread-count');
      final data = response.data is Map<String, dynamic> ? response.data : {};
      return data['data']?['count'] ?? data['count'] ?? 0;
    } catch (e) {
      debugPrint('[NotificationService] 获取公告未读数失败: $e');
      return 0;
    }
  }

  /// 标记公告已读
  Future<bool> markAnnouncementAsRead(String announcementId) async {
    try {
      await _apiClient.put('/api/v1/announcements/$announcementId/read');
      return true;
    } catch (e) {
      debugPrint('[NotificationService] 标记公告已读失败: $e');
      return false;
    }
  }

  /// 全部标记已读
  Future<bool> markAllAnnouncementsAsRead() async {
    try {
      await _apiClient.put('/api/v1/announcements/read-all');
      return true;
    } catch (e) {
      debugPrint('[NotificationService] 全部标记已读失败: $e');
      return false;
    }
  }
}
