import { render, screen, waitFor, fireEvent, act } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import { OrderDetailClient } from '../[id]/order-detail-client';
import { useAuthStore } from '@/stores/auth';

const orderGetMock = vi.fn();
const returnGetMock = vi.fn();
const messagesListMock = vi.fn();
const proactiveMock = vi.fn();

vi.mock('@/lib/api', () => ({
  api: {
    orders: { get: (...a: unknown[]) => orderGetMock(...a) },
    returns: { forStore: (storeId: string) => {
      expect(storeId).toBe('store-1');
      return {
      get: (...a: unknown[]) => returnGetMock(...a),
      proactive: (...a: unknown[]) => proactiveMock(...a),
      approve: vi.fn(),
      reject: vi.fn(),
      markReceived: vi.fn(),
      retryLabel: vi.fn(),
      };
    } },
    messages: { forStore: (storeId: string) => {
      expect(storeId).toBe('store-1');
      return {
      list: (...a: unknown[]) => messagesListMock(...a),
      post: vi.fn(),
      delete: vi.fn(),
      uploadAttachment: vi.fn(),
      };
    } },
  },
}));

function wrap(node: React.ReactNode) {
  const qc = new QueryClient({
    defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
  });
  return <QueryClientProvider client={qc}>{node}</QueryClientProvider>;
}

const baseOrder = {
  id: 'ord-1',
  store: { id: 's1', name: 'Revive' },
  buyer: { first_name: 'Jane', last_name: 'Doe' },
  shipping_address: {
    street: '1 Main St',
    city: 'Portland',
    state: 'OR',
    zip: '97201',
  },
  subtotal: 4000,
  shipping_cost: 500,
  status: 'shipped',
  shipped_at: '2026-05-06T10:00:00Z',
  tracking_number: null,
  tracking_url: null,
  carrier: null,
  delivered_at: null,
  is_delayed: false,
  open_return_id: null,
  items: [
    {
      id: 'oi1',
      item_id: 'it1',
      title_snapshot: 'Vintage Tee',
      price_snapshot: 4000,
      image_url_snapshot: null,
    },
  ],
  created_at: '2026-05-04T10:00:00Z',
};

async function renderAndFlush(node: React.ReactNode) {
  await act(async () => {
    render(node);
    await Promise.resolve();
  });
}

describe('OrderDetailClient — proactive refund', () => {
  beforeEach(() => {
    orderGetMock.mockReset();
    returnGetMock.mockReset();
    messagesListMock.mockResolvedValue({ data: [], meta: { total: 0, has_more: false } });
    proactiveMock.mockReset();
    useAuthStore.setState({
      user: {
        id: 'u-seller',
        store_id: 'store-1',
        email: 'seller@example.com',
      } as never,
      selectedStoreId: 'store-1',
      memberships: [{ id: 'm', store_id: 'store-1', role: 'owner', capabilities: ['store.admin'], is_exempt: false }],
      token: 't',
      isLoading: false,
    });
  });

  it('shows Issue refund button when there is no open return', async () => {
    orderGetMock.mockResolvedValue({ data: { ...baseOrder, open_return_id: null } });
    await renderAndFlush(wrap(<OrderDetailClient orderId="ord-1" />));
    expect(
      await screen.findByRole('button', { name: /Issue refund/i }),
    ).toBeInTheDocument();
  });

  it('hides Issue refund button when an open return exists', async () => {
    orderGetMock.mockResolvedValue({
      data: { ...baseOrder, open_return_id: 'r1' },
    });
    returnGetMock.mockResolvedValue({
      data: {
        id: 'r1',
        order_id: 'ord-1',
        initiated_by: 'buyer',
        state: 'requested',
        reason: 'damaged',
        reason_text: null,
        return_shipping_payer: 'seller',
        restocking_fee_cents: 0,
        refund_amount_cents: null,
        refund_original_shipping: false,
        refund_amount_override_cents: null,
        stripe_refund_id: null,
        tracking_number: null,
        carrier: null,
        tracker_id: null,
        tracking_url: null,
        shipping_label_url: null,
        easypost_label_error: null,
        items: [],
        approved_at: null,
        rejected_at: null,
        label_issued_at: null,
        in_transit_at: null,
        received_at: null,
        refunded_at: null,
        closed_at: null,
        cancelled_at: null,
        escalation: null,
        created_at: '2026-05-07T10:00:00Z',
        updated_at: '2026-05-07T10:00:00Z',
      },
    });
    await renderAndFlush(wrap(<OrderDetailClient orderId="ord-1" />));
    await waitFor(() =>
      expect(screen.getByText('Awaiting seller')).toBeInTheDocument(),
    );
    expect(
      screen.queryByRole('button', { name: /Issue refund/i }),
    ).toBeNull();
  });

  it('clicking Issue refund opens the modal', async () => {
    orderGetMock.mockResolvedValue({ data: { ...baseOrder, open_return_id: null } });
    await renderAndFlush(wrap(<OrderDetailClient orderId="ord-1" />));
    fireEvent.click(await screen.findByRole('button', { name: /Issue refund/i }));
    expect(
      await screen.findByRole('dialog', { name: /Issue proactive refund/i }),
    ).toBeInTheDocument();
  });
});
