const mockSupabaseFrom = jest.fn();
jest.mock('../../src/utils/supabase', () => ({
  getSupabaseServiceClient: () => ({ from: mockSupabaseFrom }),
}));

const { getAlertsForUser, markAlertRead } = require('../../src/services/alertService');

beforeEach(() => {
  jest.clearAllMocks();
});

describe('alertService', () => {
  test('getAlertsForUser returns unread alerts', async () => {
    const alerts = [
      { id: 'a1', alert_type: 'player_scratched', detail: 'Player X scratched', is_read: false },
    ];
    mockSupabaseFrom.mockImplementation(() => ({
      select: (sel, opts) => {
        if (opts?.head) {
          return {
            eq: () => ({ eq: () => Promise.resolve({ count: 1 }) }),
          };
        }
        return {
          eq: (col, val) => ({
            eq: () => ({
              order: () => Promise.resolve({ data: alerts, error: null }),
            }),
          }),
        };
      },
    }));

    const result = await getAlertsForUser('user-1');
    expect(result.alerts).toHaveLength(1);
    expect(result.unread_count).toBe(1);
  });

  test('markAlertRead returns updated alert', async () => {
    mockSupabaseFrom.mockReturnValue({
      update: () => ({
        eq: () => ({
          eq: () => ({
            select: () => ({
              single: () => Promise.resolve({ data: { id: 'a1', is_read: true }, error: null }),
            }),
          }),
        }),
      }),
    });

    const result = await markAlertRead('a1', 'user-1');
    expect(result.id).toBe('a1');
    expect(result.is_read).toBe(true);
  });

  test('markAlertRead returns null for nonexistent alert', async () => {
    mockSupabaseFrom.mockReturnValue({
      update: () => ({
        eq: () => ({
          eq: () => ({
            select: () => ({
              single: () => Promise.resolve({ data: null, error: { message: 'not found' } }),
            }),
          }),
        }),
      }),
    });

    const result = await markAlertRead('nonexistent', 'user-1');
    expect(result).toBeNull();
  });
});
