import 'dart:io';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:frontend/providers/auth.dart';
import 'package:logging/logging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'web_socket.g.dart';

final _logger = Logger('WebSocketNotifier');

@riverpod
class WebSocketNotifier extends _$WebSocketNotifier {
  @override
  Future<WebSocket?> build() async {
    return null;
  }

  Future<void> connect() async {
    state = AsyncValue.loading();
    final jwt = ref.read(jwtNotifierProvider).valueOrNull;
    final jwtBody = ref.read(jwtBodyProvider);
    if (jwt == null || jwtBody == null) {
      _logger.warning('Tried to connect to ws without jwt token');
      return;
    }

    final wsUrl = Uri.parse('ws://localhost:8080/room/${jwtBody.roomCode}/ws');
    _logger.finest('Attempting to connect to $wsUrl');

    try {
      final connection = await WebSocket.connect(wsUrl.toString(), headers: {'Authorization': 'Bearer: $jwt'});
      _logger.fine('Client ws connection established to room ${jwtBody.roomUuid}');
      state = AsyncValue.data(connection);
    } catch (e) {
      if (e is WebSocketException) {
        if (e.httpStatusCode == 401) {
          ref.read(jwtNotifierProvider.notifier).eraseJwt();
        }
      }
      _logger.warning('Error occurred creating web socket: $e');
    }
  }
}

// @riverpod
// class WebSocketStreamNotifier extends _$WebSocketStreamNotifier {
//   @override
//   Stream<dynamic> build() {
//     final connection = ref.watch(webSocketNotifierProvider).valueOrNull;
//     if (connection == null) return Stream.empty();
//     _logger.finest('Created broadcast stream from ws connection');
//     return connection.asBroadcastStream();
//   }
// }

@riverpod
Raw<Stream<dynamic>> webSocketStream(Ref ref) {
  final connection = ref.watch(webSocketNotifierProvider).valueOrNull;
  if (connection == null) return Stream.empty();
  _logger.finest('Created broadcast stream from ws connection');
  return connection.asBroadcastStream();
}