import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

import '../models/notification_item.dart';
import 'profile_provider.dart';
import 'supabase_provider.dart';
import '../utils/app_time.dart';

final notificationsProvider = StreamProvider<List<NotificationItem>>((ref) {
  final userId = ref.watch(currentUserIdProvider);
  if (userId == null) {
    return const Stream.empty();
  }
  final client = ref.watch(supabaseClientProvider);
  return client
      .from('notifications')
      .stream(primaryKey: ['id'])
      .eq('user_id', userId)
      .order('created_at', ascending: false)
      .map((rows) => rows.map(NotificationItem.fromMap).toList());
});

final unreadNotificationsCountProvider = Provider<int>((ref) {
  final notificationsAsync = ref.watch(notificationsProvider);
  return notificationsAsync.maybeWhen(
    data: (items) => items.where((item) => item.isUnread).length,
    orElse: () => 0,
  );
});

final notificationsControllerProvider = Provider<NotificationsController>((
  ref,
) {
  final client = ref.watch(supabaseClientProvider);
  return NotificationsController(client);
});

class NotificationsController {
  NotificationsController(this._client);

  final SupabaseClient _client;

  Future<void> createMentionNotifications({
    required List<String> userIds,
    required String actorId,
    required int messageId,
    String? ticketId,
    String? taskId,
  }) async {
    if (userIds.isEmpty) return;
    if ((ticketId == null || ticketId.isEmpty) &&
        (taskId == null || taskId.isEmpty)) {
      return;
    }
    final rows = userIds
        .map(
          (userId) => {
            'user_id': userId,
            'actor_id': actorId,
            'ticket_id': ticketId,
            'task_id': taskId,
            'message_id': messageId,
            'type': 'mention',
          },
        )
        .toList();
    await _client.from('notifications').insert(rows);
  }

  Future<void> markRead(String id) async {
    await _client
        .from('notifications')
        .update({'read_at': AppTime.nowUtc().toIso8601String()})
        .eq('id', id);
  }

  Future<void> markReadForTicket(String ticketId) async {
    final userId = _client.auth.currentUser?.id;
    if (userId == null) return;
    await _client
        .from('notifications')
        .update({'read_at': AppTime.nowUtc().toIso8601String()})
        .eq('ticket_id', ticketId)
        .eq('user_id', userId)
        .filter('read_at', 'is', null);
  }

  Future<void> markReadForTask(String taskId) async {
    final userId = _client.auth.currentUser?.id;
    if (userId == null) return;
    await _client
        .from('notifications')
        .update({'read_at': AppTime.nowUtc().toIso8601String()})
        .eq('task_id', taskId)
        .eq('user_id', userId)
        .filter('read_at', 'is', null);
  }
}
