import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import { useRouter, useSearchParams } from 'next/navigation';
import { useAuthStore } from '@/stores/auth';
import { SellerReviewsClient } from '../seller-reviews-client';

vi.mock('next/navigation', () => ({
  useRouter: vi.fn(),
  usePathname: vi.fn(() => '/seller/reviews'),
  useSearchParams: vi.fn(),
}));

vi.mock('@/stores/auth', () => ({
  useAuthStore: vi.fn(),
}));

const summaryMock = vi.fn();
const sellerListMock = vi.fn();
vi.mock('@/lib/api', () => ({
  api: {
    reviews: {
      sellerRatingSummary: (...a: unknown[]) => summaryMock(...a),
      sellerReviews: (...a: unknown[]) => sellerListMock(...a),
    },
  },
}));

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

const baseReview = {
  id: 'rev-1',
  order_item_id: 'oi-1',
  order_id: 'ord-1',
  store_id: 's-1',
  reviewer_user_id: 'u-1',
  rating: 5,
  rating_item_as_described: 5,
  rating_shipping_speed: 5,
  rating_communication: 5,
  rating_packaging: 5,
  title: 'Amazing',
  body: 'Great seller, would buy again.',
  state: 'visible' as const,
  edited_at: null,
  photos: [],
  created_at: '2026-05-01T10:00:00Z',
  updated_at: '2026-05-01T10:00:00Z',
};

describe('SellerReviewsClient', () => {
  const replace = vi.fn();
  let currentParams = new URLSearchParams('');

  beforeEach(() => {
    summaryMock.mockReset();
    sellerListMock.mockReset();
    replace.mockReset();
    currentParams = new URLSearchParams('');
    vi.mocked(useAuthStore).mockImplementation(((selector?: (s: unknown) => unknown) => {
      const state = { user: { store_id: 'legacy' }, selectedStoreId: 'store-1', memberships: [{ store_id: 'store-1' }], isLoading: false };
      return selector ? selector(state) : state;
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    }) as any);
    vi.mocked(useRouter).mockReturnValue({
      replace: (url: string) => {
        replace(url);
        const qs = url.split('?')[1] ?? '';
        currentParams = new URLSearchParams(qs);
      },
      push: vi.fn(),
      back: vi.fn(),
      forward: vi.fn(),
      refresh: vi.fn(),
      prefetch: vi.fn(),
    } as unknown as ReturnType<typeof useRouter>);
    vi.mocked(useSearchParams).mockImplementation(
      () => currentParams as unknown as ReturnType<typeof useSearchParams>,
    );
  });

  it('renders empty state', async () => {
    summaryMock.mockResolvedValue({
      data: {
        average_rating: null,
        review_count: 0,
        distribution: { '1': 0, '2': 0, '3': 0, '4': 0, '5': 0 },
        dimensions: {
          item_as_described: null,
          shipping_speed: null,
          communication: null,
          packaging: null,
        },
      },
    });
    sellerListMock.mockResolvedValue({
      data: [],
      meta: { current_page: 1, last_page: 1, per_page: 20, total: 0, from: null, to: null },
      links: { first: null, last: null, prev: null, next: null },
    });
    render(wrap(<SellerReviewsClient />));
    await waitFor(() =>
      expect(screen.getByTestId('seller-reviews-empty')).toBeInTheDocument(),
    );
  });

  it('renders rating header, breakdown, and review list with order link', async () => {
    summaryMock.mockResolvedValue({
      data: {
        average_rating: 4.9,
        review_count: 10,
        distribution: { '1': 0, '2': 0, '3': 0, '4': 1, '5': 9 },
        dimensions: {
          item_as_described: 5.0,
          shipping_speed: 4.8,
          communication: 4.9,
          packaging: 5.0,
        },
      },
    });
    sellerListMock.mockResolvedValue({
      data: [baseReview],
      meta: { current_page: 1, last_page: 1, per_page: 20, total: 1, from: 1, to: 1 },
      links: { first: null, last: null, prev: null, next: null },
    });
    render(wrap(<SellerReviewsClient />));
    await waitFor(() =>
      expect(screen.getByText(/Amazing/)).toBeInTheDocument(),
    );
    expect(screen.getByText(/Great seller/)).toBeInTheDocument();
    expect(screen.getByTestId('dimension-breakdown')).toBeInTheDocument();
    const orderLink = screen.getByTestId('seller-review-tx-rev-1') as HTMLAnchorElement;
    expect(orderLink.getAttribute('href')).toBe('/seller/orders/ord-1');
  });

  it('paginates via URL ?page= and triggers next page', async () => {
    summaryMock.mockResolvedValue({
      data: {
        average_rating: 4.0,
        review_count: 25,
        distribution: { '1': 0, '2': 0, '3': 5, '4': 10, '5': 10 },
        dimensions: {
          item_as_described: 4,
          shipping_speed: 4,
          communication: 4,
          packaging: 4,
        },
      },
    });
    sellerListMock.mockResolvedValue({
      data: [baseReview],
      meta: { current_page: 1, last_page: 3, per_page: 20, total: 25, from: 1, to: 1 },
      links: { first: null, last: null, prev: null, next: null },
    });
    render(wrap(<SellerReviewsClient />));
    await waitFor(() =>
      expect(screen.getByText(/Amazing/)).toBeInTheDocument(),
    );
    fireEvent.click(screen.getByRole('button', { name: /Next/i }));
    expect(replace).toHaveBeenCalledWith('/seller/reviews?page=2');
  });
});
