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 { SessionNotifier() : super(const SessionState()); void setSession(StreamSession session, {MatchModel? match}) { state = state.copyWith(session: session, match: match); } void updateYoutubeLinks({ required String? youtubeWatchUrl, required String? shareUrl, String? youtubeBroadcastId, bool youtubeReady = true, }) { final s = state.session; if (s == null || s.platform != 'youtube') return; state = state.copyWith( session: StreamSession( id: s.id, matchId: s.matchId, status: s.status, platform: s.platform, rtmpIngestUrl: s.rtmpIngestUrl, hlsPlaybackUrl: s.hlsPlaybackUrl, watchPageUrl: s.watchPageUrl, shareUrl: shareUrl, youtubeWatchUrl: youtubeWatchUrl, youtubeBroadcastId: youtubeBroadcastId ?? s.youtubeBroadcastId, youtubeReady: youtubeReady, privacyStatus: s.privacyStatus, qualityPreset: s.qualityPreset, targetBitrate: s.targetBitrate, startedAt: s.startedAt, disconnectionCount: s.disconnectionCount, score: s.score, devices: s.devices, ), ); } 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!; final incoming = device.status!; // Non sovrascrivere una pausa intenzionale con stati transitori (live/connecting). if (s.status == 'paused' && incoming != 'paused' && incoming != 'ended') { state = state.copyWith(cameraDevice: device); return; } state = state.copyWith( session: StreamSession( id: s.id, matchId: s.matchId, status: incoming, platform: s.platform, rtmpIngestUrl: s.rtmpIngestUrl, hlsPlaybackUrl: s.hlsPlaybackUrl, watchPageUrl: s.watchPageUrl, shareUrl: s.shareUrl, youtubeWatchUrl: s.youtubeWatchUrl, youtubeBroadcastId: s.youtubeBroadcastId, youtubeReady: s.youtubeReady, 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 'resume_stream': newStatus = 'connecting'; 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, shareUrl: session.shareUrl, youtubeWatchUrl: session.youtubeWatchUrl, youtubeBroadcastId: session.youtubeBroadcastId, youtubeReady: session.youtubeReady, 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((ref) { return SessionNotifier(); });