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

import { fetchMerchantContacts } from '@/services/merchantService';
import { getSupabaseClient } from '@/lib/supabase';

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

vi.mock('@/services/dataAccessScope', () => ({
  getVisibleBatchIds: vi.fn(async () => ['BATCH-001', 'BATCH-MANUAL']),
}));

type QueryResponse = {
  data: unknown[] | null;
  error: { code?: string; message: string } | null;
};

type QueryResponses = QueryResponse | QueryResponse[];

function createQuery(response: QueryResponse) {
  const query = {
    order: vi.fn(() => query),
    in: vi.fn(() => query),
    then: (onFulfilled: (value: QueryResponse) => unknown, onRejected?: (reason: unknown) => unknown) =>
      Promise.resolve(response).then(onFulfilled, onRejected),
    catch: (onRejected: (reason: unknown) => unknown) => Promise.resolve(response).catch(onRejected),
  };

  return query;
}

function createSupabaseMock(responses: Record<string, QueryResponses>) {
  const responseQueues = new Map(
    Object.entries(responses).map(([table, response]) => [
      table,
      Array.isArray(response) ? [...response] : [response],
    ]),
  );

  const nextResponseForTable = (table: string) => {
    const queue = responseQueues.get(table);
    if (!queue || queue.length === 0) {
      return { data: [], error: null };
    }

    return queue.shift() ?? { data: [], error: null };
  };

  return {
    from: vi.fn((table: string) => ({
      select: vi.fn(() => createQuery(nextResponseForTable(table))),
    })),
  };
}

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

  it('falls back to final_result_products when merchant_contacts is empty', async () => {
    vi.mocked(getSupabaseClient).mockReturnValue(createSupabaseMock({
      merchant_contacts: { data: [], error: null },
      final_result_products: {
        data: [{
          id: 'fr-001',
          batch_id: 'BATCH-001',
          material_id: 'mat-001',
          offer_url: 'https://detail.1688.com/offer/1.html',
          merchant_name: '杭州测试供应商',
          merchant_url: 'https://shop.1688.com/a',
          contact_page_url: 'https://shop.1688.com/a/contact',
          detected_contacts: [{ type: 'phone', value: '13800138000' }],
          match_bucket: 'possible',
          created_at: '2026-04-09T10:00:00.000Z',
        }],
        error: null,
      },
      standardized_results: {
        data: [{ material_id: 'mat-001', standardized_name: 'PVC-U给水管 DN100' }],
        error: null,
      },
    }) as unknown as ReturnType<typeof getSupabaseClient>);

    await expect(fetchMerchantContacts()).resolves.toEqual([
      expect.objectContaining({
        id: 'fr-001',
        merchant_name: '杭州测试供应商',
        standardized_name: 'PVC-U给水管 DN100',
        phone: '13800138000',
        mobile: '13800138000',
        source_match_bucket: 'possible',
      }),
    ]);
  });

  it('lets curated merchant_contacts override fallback values while preserving phone fallback', async () => {
    vi.mocked(getSupabaseClient).mockReturnValue(createSupabaseMock({
      merchant_contacts: {
        data: [{
          id: 'mc-001',
          merchant_url: 'https://shop.1688.com/a',
          merchant_name: '人工维护供应商',
          contact_page_url: '',
          standardized_name: '',
          contact_person: '王经理',
          phone: '0571-88886666',
          mobile: '',
          address: '浙江杭州',
          source_batch_id: 'BATCH-MANUAL',
          source_offer_url: '',
          created_at: '2026-04-08T08:00:00.000Z',
          updated_at: '2026-04-10T08:00:00.000Z',
          updated_by: 'alice',
        }],
        error: null,
      },
      final_result_products: {
        data: [{
          id: 'fr-001',
          batch_id: 'BATCH-001',
          material_id: 'mat-001',
          offer_url: 'https://detail.1688.com/offer/1.html',
          merchant_name: '流程产出供应商',
          merchant_url: 'https://shop.1688.com/a',
          contact_page_url: 'https://shop.1688.com/a/contact',
          detected_contacts: [{ type: 'mobile', value: '13800138000' }],
          match_bucket: 'possible',
          created_at: '2026-04-09T10:00:00.000Z',
        }],
        error: null,
      },
      standardized_results: {
        data: [{ material_id: 'mat-001', standardized_name: 'PPR热水管 S3.2 DN32' }],
        error: null,
      },
    }) as unknown as ReturnType<typeof getSupabaseClient>);

    await expect(fetchMerchantContacts()).resolves.toEqual([
      expect.objectContaining({
        id: 'mc-001',
        merchant_name: '人工维护供应商',
        contact_person: '王经理',
        standardized_name: 'PPR热水管 S3.2 DN32',
        phone: '0571-88886666',
        mobile: '13800138000',
        source_offer_url: 'https://detail.1688.com/offer/1.html',
        source_match_bucket: 'manual',
      }),
    ]);
  });

  it('retries final_result_products without match_bucket when the column is missing', async () => {
    vi.mocked(getSupabaseClient).mockReturnValue(createSupabaseMock({
      merchant_contacts: { data: [], error: null },
      final_result_products: [
        {
          data: null,
          error: {
            code: '42703',
            message: 'column final_result_products.match_bucket does not exist',
          },
        },
        {
          data: [{
            id: 'fr-legacy',
            batch_id: 'BATCH-001',
            material_id: 'mat-001',
            offer_url: 'https://detail.1688.com/offer/legacy.html',
            merchant_name: '旧库供应商',
            merchant_url: 'https://shop.1688.com/legacy',
            contact_page_url: 'https://shop.1688.com/legacy/contact',
            detected_contacts: [{ type: 'phone', value: '13800138002' }],
            created_at: '2026-04-11T10:00:00.000Z',
          }],
          error: null,
        },
      ],
      standardized_results: {
        data: [{ material_id: 'mat-001', standardized_name: '旧库物料' }],
        error: null,
      },
    }) as unknown as ReturnType<typeof getSupabaseClient>);

    await expect(fetchMerchantContacts()).resolves.toEqual([
      expect.objectContaining({
        id: 'fr-legacy',
        merchant_name: '旧库供应商',
        standardized_name: '旧库物料',
        phone: '13800138002',
        mobile: '13800138002',
        source_match_bucket: 'matched',
      }),
    ]);
  });

  it('prefers matched final results over possible final results for the same merchant', async () => {
    vi.mocked(getSupabaseClient).mockReturnValue(createSupabaseMock({
      merchant_contacts: { data: [], error: null },
      final_result_products: {
        data: [
          {
            id: 'fr-possible',
            batch_id: 'BATCH-001',
            material_id: 'mat-001',
            offer_url: 'https://detail.1688.com/offer/possible.html',
            merchant_name: '杭州测试供应商',
            merchant_url: 'https://shop.1688.com/a',
            contact_page_url: 'https://shop.1688.com/a/contact',
            detected_contacts: [{ type: 'phone', value: '13800138001' }],
            match_bucket: 'possible',
            created_at: '2026-04-10T10:00:00.000Z',
          },
          {
            id: 'fr-matched',
            batch_id: 'BATCH-001',
            material_id: 'mat-001',
            offer_url: 'https://detail.1688.com/offer/matched.html',
            merchant_name: '杭州测试供应商',
            merchant_url: 'https://shop.1688.com/a',
            contact_page_url: 'https://shop.1688.com/a/contact',
            detected_contacts: [{ type: 'phone', value: '13800138000' }],
            match_bucket: 'matched',
            created_at: '2026-04-09T10:00:00.000Z',
          },
        ],
        error: null,
      },
      standardized_results: {
        data: [{ material_id: 'mat-001', standardized_name: 'PVC-U给水管 DN100' }],
        error: null,
      },
    }) as unknown as ReturnType<typeof getSupabaseClient>);

    await expect(fetchMerchantContacts()).resolves.toEqual([
      expect.objectContaining({
        id: 'fr-matched',
        phone: '13800138000',
        source_match_bucket: 'matched',
      }),
    ]);
  });
});
