import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../shared/models/device_state.dart';
import '../shared/models/match.dart';
import '../shared/models/stream_session.dart';

class SessionState {
  const SessionState({
    this.session,
    this.match,
    this.elapsed = Duration.zero,
    this.connected = false,
    this.cameraDevice,
    this.viewerCount = 0,
  });

  final StreamSession? session;
  final MatchModel? match;
  final Duration elapsed;
  final bool connected;
  final DeviceStateModel? cameraDevice;
  final int viewerCount;

  SessionState copyWith({
    StreamSession? session,
    MatchModel? match,
    Duration? elapsed,
    bool? connected,
    DeviceStateModel? cameraDevice,
    int? viewerCount,
  }) {
    return SessionState(
      session: session ?? this.session,
      match: match ?? this.match,
      elapsed: elapsed ?? this.elapsed,
      connected: connected ?? this.connected,
      cameraDevice: cameraDevice ?? this.cameraDevice,
      viewerCount: viewerCount ?? this.viewerCount,
    );
  }
}

class SessionNotifier extends StateNotifier<SessionState> {
  SessionNotifier() : super(const SessionState());

  void setSession(StreamSession session, {MatchModel? match}) {
    state = state.copyWith(session: session, match: match);
  }

  void setMatch(MatchModel match) {
    state = state.copyWith(match: match);
  }

  void setElapsed(Duration elapsed) {
    state = state.copyWith(elapsed: elapsed);
  }

  void setConnected(bool connected) {
    state = state.copyWith(connected: connected);
  }

  void setCameraDevice(DeviceStateModel? device) {
    state = state.copyWith(cameraDevice: device);
  }

  void setViewerCount(int count) {
    state = state.copyWith(viewerCount: count);
  }

  void updateDeviceState(DeviceStateModel device) {
    if (device.deviceRole == 'camera') {
      state = state.copyWith(cameraDevice: device);
    }
    if (device.status != null && state.session != null) {
      final s = state.session!;
      state = state.copyWith(
        session: StreamSession(
          id: s.id,
          matchId: s.matchId,
          status: device.status!,
          platform: s.platform,
          rtmpIngestUrl: s.rtmpIngestUrl,
          hlsPlaybackUrl: s.hlsPlaybackUrl,
          watchPageUrl: s.watchPageUrl,
          youtubeBroadcastId: s.youtubeBroadcastId,
          privacyStatus: s.privacyStatus,
          qualityPreset: s.qualityPreset,
          targetBitrate: s.targetBitrate,
          startedAt: s.startedAt,
          disconnectionCount: s.disconnectionCount,
          score: s.score,
          devices: s.devices,
        ),
      );
    }
  }

  void applyCommand(String action) {
    final session = state.session;
    if (session == null) return;

    String newStatus = session.status;
    switch (action) {
      case 'start_stream':
        newStatus = 'live';
        break;
      case 'pause_stream':
        newStatus = 'paused';
        break;
      case 'stop_stream':
        newStatus = 'ended';
        break;
    }

    if (newStatus != session.status) {
      state = state.copyWith(
        session: StreamSession(
          id: session.id,
          matchId: session.matchId,
          status: newStatus,
          platform: session.platform,
          rtmpIngestUrl: session.rtmpIngestUrl,
          hlsPlaybackUrl: session.hlsPlaybackUrl,
          watchPageUrl: session.watchPageUrl,
          youtubeBroadcastId: session.youtubeBroadcastId,
          privacyStatus: session.privacyStatus,
          qualityPreset: session.qualityPreset,
          targetBitrate: session.targetBitrate,
          startedAt: session.startedAt,
          disconnectionCount: session.disconnectionCount,
          score: session.score,
          devices: session.devices,
        ),
      );
    }
  }

  void clear() {
    state = const SessionState();
  }
}

final sessionProvider =
    StateNotifierProvider<SessionNotifier, SessionState>((ref) {
  return SessionNotifier();
});
