// src/admin/orders/__tests__/useOrders.test.js
import { renderHook, act } from '@testing-library/react';
import { vi, describe, it, expect, beforeEach } from 'vitest';

const mockChannel = vi.hoisted(() => ({
  on: vi.fn().mockReturnThis(),
  subscribe: vi.fn().mockReturnThis(),
}));

vi.mock('../../../lib/supabase', () => ({
  supabase: {
    from: vi.fn(),
    channel: vi.fn(() => mockChannel),
    removeChannel: vi.fn(),
  },
}));

import { useOrders } from '../useOrders';
import { supabase } from '../../../lib/supabase';

function makeFromMock(resolvedValue) {
  return {
    select: vi.fn().mockReturnThis(),
    order: vi.fn().mockResolvedValue(resolvedValue),
    update: vi.fn().mockReturnThis(),
    insert: vi.fn().mockResolvedValue({ error: null }),
    eq: vi.fn().mockResolvedValue({ data: null, error: null }),
    single: vi.fn().mockResolvedValue({ data: null, error: null }),
  };
}

describe('useOrders', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockChannel.on.mockReturnThis();
    mockChannel.subscribe.mockReturnThis();
  });

  it('starts with loading=true and empty orders', () => {
    supabase.from.mockReturnValue({
      select: vi.fn().mockReturnThis(),
      order: vi.fn().mockReturnValue(new Promise(() => {})),
    });
    const { result } = renderHook(() => useOrders());
    expect(result.current.loading).toBe(true);
    expect(result.current.orders).toEqual([]);
  });

  it('populates orders and sets loading=false after fetch', async () => {
    const mockOrders = [
      { id: '1', name: 'Иванов', status: 'новая', created_at: '2026-01-01' },
      { id: '2', name: 'Петров', status: 'замер', created_at: '2026-01-02' },
    ];
    supabase.from.mockReturnValue(makeFromMock({ data: mockOrders, error: null }));
    const { result } = renderHook(() => useOrders());
    await act(async () => {});
    expect(result.current.loading).toBe(false);
    expect(result.current.orders).toEqual(mockOrders);
  });

  it('groups orders by status in ordersByStatus', async () => {
    const mockOrders = [
      { id: '1', name: 'А', status: 'новая', created_at: '2026-01-01' },
      { id: '2', name: 'Б', status: 'замер', created_at: '2026-01-02' },
      { id: '3', name: 'В', status: 'новая', created_at: '2026-01-03' },
    ];
    supabase.from.mockReturnValue(makeFromMock({ data: mockOrders, error: null }));
    const { result } = renderHook(() => useOrders());
    await act(async () => {});
    expect(result.current.ordersByStatus['новая']).toHaveLength(2);
    expect(result.current.ordersByStatus['замер']).toHaveLength(1);
    expect(result.current.ordersByStatus['согласование']).toHaveLength(0);
    expect(result.current.ordersByStatus['монтаж']).toHaveLength(0);
    expect(result.current.ordersByStatus['закрыт']).toHaveLength(0);
  });

  it('sets error when fetch fails', async () => {
    supabase.from.mockReturnValue(makeFromMock({ data: null, error: { message: 'DB error' } }));
    const { result } = renderHook(() => useOrders());
    await act(async () => {});
    expect(result.current.error).toBe('DB error');
  });
});
