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

import '../../services/notification_service.dart';

import '../../providers/notifications_provider.dart';
import '../../providers/profile_provider.dart';
import '../../providers/tasks_provider.dart';
import '../../providers/tickets_provider.dart';
import '../../widgets/mono_text.dart';
import '../../widgets/responsive_body.dart';
import '../../theme/app_surfaces.dart';

class NotificationsScreen extends ConsumerStatefulWidget {
  const NotificationsScreen({super.key});

  @override
  ConsumerState<NotificationsScreen> createState() =>
      _NotificationsScreenState();
}

class _NotificationsScreenState extends ConsumerState<NotificationsScreen> {
  bool _showBanner = false;
  bool _dismissed = false;

  @override
  void initState() {
    super.initState();
    _checkChannel();
  }

  Future<void> _checkChannel() async {
    final muted = await NotificationService.isHighPriorityChannelMuted();
    if (!mounted) return;
    if (muted) {
      setState(() => _showBanner = true);
    }
  }

  @override
  Widget build(BuildContext context) {
    final notificationsAsync = ref.watch(notificationsProvider);
    final profilesAsync = ref.watch(profilesProvider);
    final ticketsAsync = ref.watch(ticketsProvider);
    final tasksAsync = ref.watch(tasksProvider);

    final profileById = {
      for (final profile in profilesAsync.valueOrNull ?? [])
        profile.id: profile,
    };
    final ticketById = {
      for (final ticket in ticketsAsync.valueOrNull ?? []) ticket.id: ticket,
    };
    final taskById = {
      for (final task in tasksAsync.valueOrNull ?? []) task.id: task,
    };

    return ResponsiveBody(
      child: notificationsAsync.when(
        data: (items) {
          if (items.isEmpty) {
            return const Center(child: Text('No notifications yet.'));
          }
          return Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Padding(
                padding: const EdgeInsets.only(top: 16, bottom: 8),
                child: Text(
                  'Notifications',
                  style: Theme.of(
                    context,
                  ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w700),
                ),
              ),
              if (_showBanner && !_dismissed)
                Padding(
                  padding: const EdgeInsets.only(bottom: 12),
                  child: MaterialBanner(
                    content: const Text(
                      'Push notifications are currently silenced. Tap here to fix.',
                    ),
                    actions: [
                      TextButton(
                        onPressed: () {
                          openAppSettings();
                        },
                        child: const Text('Open settings'),
                      ),
                      TextButton(
                        onPressed: () {
                          setState(() => _dismissed = true);
                        },
                        child: const Text('Dismiss'),
                      ),
                    ],
                  ),
                ),
              Expanded(
                child: ListView.separated(
                  padding: const EdgeInsets.only(bottom: 24),
                  itemCount: items.length,
                  separatorBuilder: (context, index) =>
                      const SizedBox(height: 12),
                  itemBuilder: (context, index) {
                    final item = items[index];
                    final actorName = item.actorId == null
                        ? 'System'
                        : (profileById[item.actorId]?.fullName ??
                              item.actorId!);
                    final ticketSubject = item.ticketId == null
                        ? 'Ticket'
                        : (ticketById[item.ticketId]?.subject ??
                              item.ticketId!);
                    final taskTitle = item.taskId == null
                        ? 'Task'
                        : (taskById[item.taskId]?.title ?? item.taskId!);
                    final subtitle = item.taskId != null
                        ? taskTitle
                        : ticketSubject;

                    final title = _notificationTitle(item.type, actorName);
                    final icon = _notificationIcon(item.type);

                    // Use a slightly more compact card for dense notification lists
                    // — 12px radius, subtle shadow so the list remains readable.
                    return Card(
                      shape: AppSurfaces.of(context).compactShape,
                      shadowColor: AppSurfaces.of(context).compactShadowColor,
                      child: ListTile(
                        leading: Icon(icon),
                        title: Text(title),
                        subtitle: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(subtitle),
                            const SizedBox(height: 4),
                            if (item.ticketId != null)
                              MonoText('Ticket ${item.ticketId}')
                            else if (item.taskId != null)
                              MonoText('Task ${item.taskId}'),
                          ],
                        ),
                        trailing: item.isUnread
                            ? const Icon(
                                Icons.circle,
                                size: 10,
                                color: Colors.red,
                              )
                            : null,
                        onTap: () async {
                          final ticketId = item.ticketId;
                          final taskId = item.taskId;
                          if (ticketId != null) {
                            await ref
                                .read(notificationsControllerProvider)
                                .markReadForTicket(ticketId);
                          } else if (taskId != null) {
                            await ref
                                .read(notificationsControllerProvider)
                                .markReadForTask(taskId);
                          } else if (item.isUnread) {
                            await ref
                                .read(notificationsControllerProvider)
                                .markRead(item.id);
                          }
                          if (!context.mounted) return;
                          if (taskId != null) {
                            context.go('/tasks/$taskId');
                          } else if (ticketId != null) {
                            context.go('/tickets/$ticketId');
                          }
                        },
                      ),
                    );
                  },
                ),
              ),
            ],
          );
        },
        loading: () => const Center(child: CircularProgressIndicator()),
        error: (error, _) =>
            Center(child: Text('Failed to load notifications: $error')),
      ),
    );
  }

  String _notificationTitle(String type, String actorName) {
    switch (type) {
      case 'assignment':
        return '$actorName assigned you';
      case 'created':
        return '$actorName created a new item';
      case 'swap_request':
        return '$actorName requested a shift swap';
      case 'swap_update':
        return '$actorName updated a swap request';
      case 'mention':
      default:
        return '$actorName mentioned you';
    }
  }

  IconData _notificationIcon(String type) {
    switch (type) {
      case 'assignment':
        return Icons.assignment_ind_outlined;
      case 'created':
        return Icons.campaign_outlined;
      case 'swap_request':
        return Icons.swap_horiz;
      case 'swap_update':
        return Icons.update;
      case 'mention':
      default:
        return Icons.alternate_email;
    }
  }
}
