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

import { getSupabaseClient } from '@/lib/supabase';
import {
  createProcurementDictionaryEntry,
  deleteProcurementDictionaryEntry,
  fetchProcurementDictionaryEntries,
  updateProcurementDictionaryEntry,
} from '@/services/modelOverrideService';

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

describe('procurement dictionary service', () => {
  beforeEach(() => {
    vi.resetAllMocks();
  });

  it('fetches procurement dictionary entries ordered by latest update', async () => {
    const order = vi.fn(async () => ({ data: [{ id: 'entry-1', term: '2R' }], error: null }));
    const select = vi.fn(() => ({ order }));
    const from = vi.fn(() => ({ select }));
    vi.mocked(getSupabaseClient).mockReturnValue({ from } as unknown as ReturnType<typeof getSupabaseClient>);

    await expect(fetchProcurementDictionaryEntries()).resolves.toEqual([{ id: 'entry-1', term: '2R' }]);
    expect(from).toHaveBeenCalledWith('procurement_dictionary_entries');
    expect(select).toHaveBeenCalledWith('*');
    expect(order).toHaveBeenCalledWith('updated_at', { ascending: false });
  });

  it('creates a trimmed procurement dictionary entry', async () => {
    const single = vi.fn(async () => ({ data: { id: 'entry-1', term: '2R' }, error: null }));
    const select = vi.fn(() => ({ single }));
    const insert = vi.fn(() => ({ select }));
    const from = vi.fn(() => ({ insert }));
    vi.mocked(getSupabaseClient).mockReturnValue({ from } as unknown as ReturnType<typeof getSupabaseClient>);

    await createProcurementDictionaryEntry({
      term: ' 2R ',
      term_type: 'parameter',
      product_context: ' 丁基防水胶带 ',
      interpretation: ' 双面防水 ',
      suggested_keyword: ' 2R丁基防水胶带 ',
      evidence: ' 行业语境 ',
      note: ' 自动沉淀 ',
    }, 'user-1');

    expect(insert).toHaveBeenCalledWith({
      term: '2R',
      term_type: 'parameter',
      product_context: '丁基防水胶带',
      interpretation: '双面防水',
      suggested_keyword: '2R丁基防水胶带',
      evidence: '行业语境',
      note: '自动沉淀',
      created_by: 'user-1',
    });
  });

  it('updates and deletes procurement dictionary entries', async () => {
    const updateEq = vi.fn(() => ({ select: vi.fn(() => ({ single: vi.fn(async () => ({ data: { id: 'entry-1' }, error: null })) })) }));
    const update = vi.fn(() => ({ eq: updateEq }));
    const deleteEq = vi.fn(async () => ({ error: null }));
    const deleteFn = vi.fn(() => ({ eq: deleteEq }));
    const from = vi.fn((table: string) => {
      expect(table).toBe('procurement_dictionary_entries');
      return { update, delete: deleteFn };
    });
    vi.mocked(getSupabaseClient).mockReturnValue({ from } as unknown as ReturnType<typeof getSupabaseClient>);

    await updateProcurementDictionaryEntry('entry-1', {
      term: ' GEB371 ',
      term_type: 'unique_model',
      interpretation: ' 外挂电池 ',
      suggested_keyword: ' GEB371外挂电池 ',
      evidence: '',
      note: '',
    });
    await deleteProcurementDictionaryEntry('entry-1');

    expect(update).toHaveBeenCalledWith(expect.objectContaining({
      term: 'GEB371',
      term_type: 'unique_model',
      interpretation: '外挂电池',
      suggested_keyword: 'GEB371外挂电池',
      note: null,
    }));
    expect(updateEq).toHaveBeenCalledWith('id', 'entry-1');
    expect(deleteFn).toHaveBeenCalledTimes(1);
    expect(deleteEq).toHaveBeenCalledWith('id', 'entry-1');
  });
});
