import { beforeEach, describe, expect, it, vi } from 'vitest';

import { getSupabaseClient } from '@/lib/supabase';
import {
  getCurrentDataAccessScope,
  getVisibleBatchIdsForScope,
} from '@/services/dataAccessScope';

vi.mock('@/lib/supabase', () => ({
  getSupabaseClient: vi.fn(),
}));

vi.mock('@/services/dataAccessScope', () => ({
  getCurrentDataAccessScope: vi.fn(),
  getVisibleBatchIdsForScope: vi.fn(),
}));

import { fetchInquiryTasks } from '@/services/inquiryService';

function createQuery(response: { data: unknown[] | null; error: { message: string } | null }) {
  const query = {
    in: vi.fn(() => query),
    eq: vi.fn(() => query),
    order: vi.fn(() => query),
    then: (onFulfilled: (value: typeof response) => unknown, onRejected?: (reason: unknown) => unknown) =>
      Promise.resolve(response).then(onFulfilled, onRejected),
    catch: (onRejected: (reason: unknown) => unknown) => Promise.resolve(response).catch(onRejected),
  };

  return query;
}

describe('inquiryService', () => {
  beforeEach(() => {
    vi.resetAllMocks();
  });

  it('returns empty when the requested batch is outside the visible scope', async () => {
    vi.mocked(getCurrentDataAccessScope).mockResolvedValue({
      userId: 'user-001',
      role: 'user',
      isAdmin: false,
      accessToken: 'token-001',
    });
    vi.mocked(getVisibleBatchIdsForScope).mockResolvedValue(['CG-20260420-001']);

    const supabase = {
      from: vi.fn(),
    };
    vi.mocked(getSupabaseClient).mockReturnValue(supabase as unknown as ReturnType<typeof getSupabaseClient>);

    await expect(fetchInquiryTasks({ batchId: 'CG-20260420-999' })).resolves.toEqual([]);
    expect(supabase.from).not.toHaveBeenCalled();
  });

  it('applies visible batch filtering before loading inquiry chats', async () => {
    vi.mocked(getCurrentDataAccessScope).mockResolvedValue({
      userId: 'user-002',
      role: 'user',
      isAdmin: false,
      accessToken: 'token-002',
    });
    vi.mocked(getVisibleBatchIdsForScope).mockResolvedValue(['CG-20260420-002']);

    const chatsQuery = createQuery({
      data: [{
        id: 'chat-001',
        batch_id: 'CG-20260420-002',
        search_result_id: null,
        merchant_name: '商家 A',
        merchant_url: 'https://shop.example.com/a',
        contact_url: 'https://contact.example.com/a',
        offer_url: 'https://offer.example.com/a',
        title: '不锈钢护栏',
        current_round: 1,
        status: 'PENDING_SEND',
        retry_count: 0,
        extracted_data: null,
        ask_context: null,
        last_interacted_at: null,
        created_at: '2026-04-20T00:00:00.000Z',
        updated_at: '2026-04-20T00:00:00.000Z',
      }],
      error: null,
    });
    const messagesQuery = createQuery({ data: [], error: null });

    vi.mocked(getSupabaseClient).mockReturnValue({
      from: vi.fn((table: string) => {
        if (table === 'customer_service_chats') {
          return {
            select: vi.fn(() => chatsQuery),
          };
        }

        if (table === 'chat_messages') {
          return {
            select: vi.fn(() => messagesQuery),
          };
        }

        throw new Error(`Unexpected table: ${table}`);
      }),
    } as unknown as ReturnType<typeof getSupabaseClient>);

    await expect(fetchInquiryTasks()).resolves.toEqual([
      expect.objectContaining({
        id: 'chat-001',
        batch_id: 'CG-20260420-002',
        merchant_name: '商家 A',
      }),
    ]);

    expect(chatsQuery.in).toHaveBeenCalledWith('batch_id', ['CG-20260420-002']);
  });
});