import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter_riverpod/flutter_riverpod.dart';

class E2eeDiagEntry {
  final DateTime timestamp;
  final String roomId;
  final String eventId;
  final String sessionId;
  final String error;

  const E2eeDiagEntry({
    required this.timestamp,
    required this.roomId,
    required this.eventId,
    required this.sessionId,
    required this.error,
  });

  Map<String, dynamic> toJson() => {
        'ts': timestamp.toIso8601String(),
        'room': roomId,
        'event': eventId,
        'session': sessionId,
        'error': error,
      };
}

class E2eeDiagnosticsNotifier extends Notifier<List<E2eeDiagEntry>> {
  static const int _maxEntries = 500;

  @override
  List<E2eeDiagEntry> build() => [];

  void add(E2eeDiagEntry entry) {
    final next = [...state, entry];
    state = next.length > _maxEntries ? next.sublist(next.length - _maxEntries) : next;
  }

  void clear() => state = [];

  Future<String> upload({required String serverUrl, required String token}) async {
    if (state.isEmpty) return 'Keine Diagnosedaten vorhanden.';

    final payload = utf8.encode(jsonEncode({
      'client': 'Pyramid',
      'uploaded_at': DateTime.now().toIso8601String(),
      'entry_count': state.length,
      'entries': state.map((e) => e.toJson()).toList(),
    }));

    final client = HttpClient();
    try {
      final uri = Uri.parse('$serverUrl/api/e2ee-diagnostics');
      final request = await client.postUrl(uri);
      request.headers.set('Content-Type', 'application/json; charset=utf-8');
      request.headers.set('Authorization', 'Bearer $token');
      request.headers.contentLength = payload.length;
      request.add(payload);
      final response = await request.close();
      await response.drain<void>();
      if (response.statusCode == 200) {
        final count = state.length;
        clear();
        return '$count Einträge hochgeladen und lokal gelöscht.';
      }
      return 'Server-Fehler: HTTP ${response.statusCode}';
    } on SocketException catch (e) {
      return 'Netzwerkfehler: ${e.message}';
    } catch (e) {
      return 'Fehler: $e';
    } finally {
      client.close();
    }
  }
}

final e2eeDiagnosticsProvider =
    NotifierProvider<E2eeDiagnosticsNotifier, List<E2eeDiagEntry>>(
  E2eeDiagnosticsNotifier.new,
);
