// Version: 1.1.0 | Created: 2026-04-01
// IncomingCallOverlay — full-screen overlay shown when an m.call.invite
// arrives. Displays caller name/avatar, and Accept / Decline buttons.

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../data/matrixrtc_repository.dart';
import '../domain/incoming_call.dart';

part 'incoming_call_overlay.g.dart';

// ---------------------------------------------------------------------------
// Provider that surfaces the latest incoming call (or null when idle)
// ---------------------------------------------------------------------------

@riverpod
Stream<IncomingCall?> incomingCallStream(Ref ref) async* {
  yield null; // idle initial state
  final repo = ref.watch(matrixRtcRepositoryProvider);
  await for (final call in repo.incomingCallStream) {
    yield call;
  }
}

// ---------------------------------------------------------------------------
// Widget
// ---------------------------------------------------------------------------

/// Wrap this around the top-level router widget to detect and display incoming
/// calls. Listens to [incomingCallStreamProvider] and shows the overlay when
/// a call arrives.
class IncomingCallOverlayHost extends ConsumerWidget {
  const IncomingCallOverlayHost({super.key, required this.child});

  final Widget child;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final callAsync = ref.watch(incomingCallStreamProvider);

    return Stack(
      children: [
        child,
        callAsync.when(
          loading: () => const SizedBox.shrink(),
          error: (_, __) => const SizedBox.shrink(),
          data: (call) {
            if (call == null) return const SizedBox.shrink();
            return _IncomingCallOverlay(call: call);
          },
        ),
      ],
    );
  }
}

class _IncomingCallOverlay extends ConsumerWidget {
  const _IncomingCallOverlay({required this.call});

  final IncomingCall call;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final theme = Theme.of(context);

    return Positioned.fill(
      child: Material(
        color: Colors.black.withAlpha(220),
        child: SafeArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // Caller avatar
              _CallerAvatar(call: call),
              const SizedBox(height: 24),

              // Caller name
              Text(
                call.callerDisplayName.isNotEmpty
                    ? call.callerDisplayName
                    : call.callerId,
                style: theme.textTheme.headlineMedium?.copyWith(
                  color: Colors.white,
                  fontWeight: FontWeight.w600,
                ),
              ),
              const SizedBox(height: 8),
              Text(
                call.isVideo ? 'Incoming video call' : 'Incoming voice call',
                style: TextStyle(
                  color: Colors.white.withAlpha(179),
                  fontSize: 16,
                ),
              ),
              const SizedBox(height: 64),

              // Accept / Decline
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  _CallActionButton(
                    icon: Icons.call_end,
                    label: 'Decline',
                    colour: Colors.red,
                    onTap: () {
                      // Dismiss the overlay by navigating away; the repository
                      // stream will emit null on the next event cycle.
                    },
                  ),
                  _CallActionButton(
                    icon: call.isVideo ? Icons.videocam : Icons.call,
                    label: 'Accept',
                    colour: Colors.green,
                    onTap: () {
                      context.push(
                        '/calls/${Uri.encodeComponent(call.roomId)}',
                      );
                    },
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _CallerAvatar extends StatelessWidget {
  const _CallerAvatar({required this.call});

  final IncomingCall call;

  @override
  Widget build(BuildContext context) {
    final initials = call.callerDisplayName.isNotEmpty
        ? call.callerDisplayName[0].toUpperCase()
        : '?';

    if (call.callerAvatarUrl != null) {
      return CircleAvatar(
        radius: 56,
        backgroundImage: CachedNetworkImageProvider(call.callerAvatarUrl!),
      );
    }

    return CircleAvatar(
      radius: 56,
      backgroundColor: Theme.of(context).colorScheme.primary.withAlpha(77),
      child: Text(
        initials,
        style: const TextStyle(
          fontSize: 40,
          color: Colors.white,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

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

  final IconData icon;
  final String label;
  final Color colour;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
            width: 72,
            height: 72,
            decoration: BoxDecoration(color: colour, shape: BoxShape.circle),
            child: Icon(icon, color: Colors.white, size: 32),
          ),
          const SizedBox(height: 8),
          Text(
            label,
            style: const TextStyle(color: Colors.white, fontSize: 14),
          ),
        ],
      ),
    );
  }
}
