// Version: 1.1.0 | Created: 2026-04-01
// Full call screen with LiveKit video/audio.
// - Remote video: full screen background
// - Local video: picture-in-picture overlay (bottom right)
// - Controls: mute, toggle video, end call
// - Duration timer and participant name

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' show RTCVideoViewObjectFit;
import 'package:go_router/go_router.dart';
import 'package:livekit_client/livekit_client.dart';

import '../data/livekit_service.dart';
import '../domain/call_state.dart';
import 'call_controller.dart';

class CallScreen extends ConsumerStatefulWidget {
  const CallScreen({super.key, required this.roomId});

  final String roomId;

  @override
  ConsumerState<CallScreen> createState() => _CallScreenState();
}

class _CallScreenState extends ConsumerState<CallScreen> {
  @override
  void initState() {
    super.initState();
    // Start the call as soon as the screen opens.
    // Using addPostFrameCallback so the provider is ready.
    WidgetsBinding.instance.addPostFrameCallback((_) {
      ref
          .read(callControllerProvider.notifier)
          .joinCall(widget.roomId, withVideo: true);
    });
  }

  @override
  Widget build(BuildContext context) {
    final callState = ref.watch(callControllerProvider);

    // Pop back automatically when call ends.
    ref.listen<CallState>(callControllerProvider, (_, next) {
      if (next is CallEnded && context.canPop()) {
        context.pop();
      }
    });

    return Scaffold(
      backgroundColor: Colors.black,
      body: SafeArea(
        child: Stack(
          children: [
            // Remote video — full screen
            const _RemoteVideoView(),

            // Local PiP — bottom right
            if (callState is CallActive && callState.isVideoEnabled)
              const _LocalVideoPip(),

            // Connecting / connecting overlay
            if (callState is CallConnecting) const _ConnectingOverlay(),

            // Call controls — pinned to bottom
            Positioned(
              left: 0,
              right: 0,
              bottom: 24,
              child: _CallControls(roomId: widget.roomId),
            ),

            // Participant info — top left
            Positioned(
              top: 16,
              left: 16,
              child: _CallInfo(callState: callState),
            ),
          ],
        ),
      ),
    );
  }
}

// ---------------------------------------------------------------------------
// Remote video view
// ---------------------------------------------------------------------------

class _RemoteVideoView extends ConsumerWidget {
  const _RemoteVideoView();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final room = ref.watch(liveKitServiceProvider).activeRoom;
    if (room == null) {
      return const _NoVideoPlaceholder();
    }

    final remoteParticipants = room.remoteParticipants.values.toList();
    if (remoteParticipants.isEmpty) {
      return const _NoVideoPlaceholder();
    }

    // Show the first remote participant's first video track.
    final firstParticipant = remoteParticipants.first;
    final videoPubs = firstParticipant.videoTrackPublications;
    if (videoPubs.isEmpty || videoPubs.first.track == null) {
      return const _NoVideoPlaceholder();
    }

    // safe: checked non-null above
    final videoTrack = videoPubs.first.track!;
    return VideoTrackRenderer(
      videoTrack,
      fit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
    );
  }
}

// ---------------------------------------------------------------------------
// Local PiP
// ---------------------------------------------------------------------------

class _LocalVideoPip extends ConsumerWidget {
  const _LocalVideoPip();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final room = ref.watch(liveKitServiceProvider).activeRoom;
    final local = room?.localParticipant;
    if (local == null) return const SizedBox.shrink();

    final videoPubs = local.videoTrackPublications;
    if (videoPubs.isEmpty || videoPubs.first.track == null) {
      return const SizedBox.shrink();
    }

    // safe: checked non-null above
    final localTrack = videoPubs.first.track!;
    return Positioned(
      right: 16,
      bottom: 120,
      child: Container(
        width: 100,
        height: 150,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(12),
          border: Border.all(color: Colors.white38, width: 1),
        ),
        clipBehavior: Clip.hardEdge,
        child: VideoTrackRenderer(
          localTrack,
          mirrorMode: VideoViewMirrorMode.mirror,
        ),
      ),
    );
  }
}

// ---------------------------------------------------------------------------
// Placeholders and overlays
// ---------------------------------------------------------------------------

class _NoVideoPlaceholder extends StatelessWidget {
  const _NoVideoPlaceholder();

  @override
  Widget build(BuildContext context) {
    return Container(
      color: const Color(0xFF1A1A2E),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              Icons.person_outline,
              size: 96,
              color: Colors.white.withAlpha(77),
            ),
            const SizedBox(height: 12),
            Text(
              'Waiting for video...',
              style: TextStyle(
                color: Colors.white.withAlpha(153),
                fontSize: 16,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _ConnectingOverlay extends StatelessWidget {
  const _ConnectingOverlay();

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.black.withAlpha(153),
      child: const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(color: Colors.white),
            SizedBox(height: 16),
            Text(
              'Connecting...',
              style: TextStyle(color: Colors.white, fontSize: 18),
            ),
          ],
        ),
      ),
    );
  }
}

// ---------------------------------------------------------------------------
// Call info (top)
// ---------------------------------------------------------------------------

class _CallInfo extends StatelessWidget {
  const _CallInfo({required this.callState});

  final CallState callState;

  @override
  Widget build(BuildContext context) {
    final durationText = switch (callState) {
      CallActive(:final duration) => _formatDuration(duration),
      CallConnecting() => 'Connecting…',
      _ => '',
    };

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (durationText.isNotEmpty)
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
            decoration: BoxDecoration(
              color: Colors.black54,
              borderRadius: BorderRadius.circular(8),
            ),
            child: Text(
              durationText,
              style: const TextStyle(
                color: Colors.white,
                fontSize: 14,
                fontFeatures: [FontFeature.tabularFigures()],
              ),
            ),
          ),
      ],
    );
  }

  String _formatDuration(Duration d) {
    final minutes = d.inMinutes.remainder(60).toString().padLeft(2, '0');
    final seconds = d.inSeconds.remainder(60).toString().padLeft(2, '0');
    return '${d.inHours > 0 ? '${d.inHours}:' : ''}$minutes:$seconds';
  }
}

// ---------------------------------------------------------------------------
// Call controls (bottom)
// ---------------------------------------------------------------------------

class _CallControls extends ConsumerWidget {
  const _CallControls({required this.roomId});

  final String roomId;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final callState = ref.watch(callControllerProvider);
    final notifier = ref.read(callControllerProvider.notifier);

    final isAudioEnabled = callState is CallActive
        ? callState.isAudioEnabled
        : true;
    final isVideoEnabled = callState is CallActive
        ? callState.isVideoEnabled
        : true;

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        // Mute button
        _ControlButton(
          icon: isAudioEnabled ? Icons.mic : Icons.mic_off,
          label: isAudioEnabled ? 'Mute' : 'Unmute',
          onTap: () => notifier.toggleAudio(),
          active: isAudioEnabled,
        ),
        // End call button — prominent red
        GestureDetector(
          onTap: () async {
            await notifier.endCall();
            if (context.mounted && context.canPop()) context.pop();
          },
          child: Container(
            width: 72,
            height: 72,
            decoration: const BoxDecoration(
              color: Colors.red,
              shape: BoxShape.circle,
            ),
            child: const Icon(Icons.call_end, color: Colors.white, size: 32),
          ),
        ),
        // Video toggle
        _ControlButton(
          icon: isVideoEnabled ? Icons.videocam : Icons.videocam_off,
          label: isVideoEnabled ? 'Hide video' : 'Show video',
          onTap: () => notifier.toggleVideo(),
          active: isVideoEnabled,
        ),
      ],
    );
  }
}

class _ControlButton extends StatelessWidget {
  const _ControlButton({
    required this.icon,
    required this.label,
    required this.onTap,
    required this.active,
  });

  final IconData icon;
  final String label;
  final VoidCallback onTap;
  final bool active;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
            width: 56,
            height: 56,
            decoration: BoxDecoration(
              color: active
                  ? Colors.white.withAlpha(51)
                  : Colors.white.withAlpha(26),
              shape: BoxShape.circle,
            ),
            child: Icon(icon, color: Colors.white, size: 24),
          ),
          const SizedBox(height: 6),
          Text(
            label,
            style: const TextStyle(color: Colors.white70, fontSize: 11),
          ),
        ],
      ),
    );
  }
}
