import { describe, it, expect, beforeEach, vi } from 'vitest';
import { screen, fireEvent, waitFor } from '@testing-library/react';
import { renderWithProviders } from '@/test/utils';

vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
vi.mock('@/lib/api', () => ({
    api: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), put: vi.fn(), delete: vi.fn() },
    ApiError: class extends Error {},
}));

import { api } from '@/lib/api';
import BlogReviewPage from '@/pages/BlogReviewPage';

const get = api.get as ReturnType<typeof vi.fn>;

/** ردیف صف — همان شکل `toListArray()`: بدون body و faq و sources. */
const ROW = {
    uuid: 'b-1',
    title: 'لیزر موهای زائد چطور کار می‌کند؟',
    slug: 'laser',
    summary: 'خلاصهٔ کوتاه',
    image_url: null,
    tags: ['پوست'],
    status: 'draft',
    review_status: 'pending_review',
    topic_slug: 'skin/laser',
    created_at: 1_700_000_000,
};

/** پاسخ اندپوینت جزئیات — double-nested، همان قرارداد فرم ویرایش مقاله. */
const DETAIL = {
    success: true,
    data: {
        data: {
            ...ROW,
            body: '<p>متن کامل مقاله اینجاست.</p>',
            reading_time: 7,
            primary_keyword: 'لیزر موهای زائد',
            faq: [{ q: 'چند جلسه لازم است؟', a: 'معمولاً شش تا هشت جلسه.' }],
            sources: [{ url: 'https://example.org/a', title: 'راهنمای پوست' }],
        },
    },
};

function mockApi(detail: unknown = DETAIL) {
    get.mockImplementation((url: string) => {
        if (url.includes('/review-queue')) {
            return Promise.resolve({
                success: true,
                data: [ROW],
                meta: { totalRecords: 1, totalPages: 1, currentPage: 1 },
                errors: [],
            });
        }
        return Promise.resolve(detail);
    });
}

describe('BlogReviewPage — مودال بازبینی', () => {
    beforeEach(() => { get.mockReset(); mockApi(); });

    /**
     * صف با `toListArray()` ساخته می‌شود و `body` ندارد؛ مودال باید متن کامل را از
     * اندپوینت جزئیات بگیرد، وگرنه بازبین یک قاب خالی می‌بیند.
     */
    it('با کلیک روی بازبینی، متن کامل مقاله را می‌گیرد و نشان می‌دهد', async () => {
        renderWithProviders(<BlogReviewPage />, { route: '/admin/blog-review' });

        fireEvent.click(await screen.findByRole('button', { name: 'بازبینی' }));

        await waitFor(() => expect(screen.getByText('متن کامل مقاله اینجاست.')).toBeInTheDocument());
        expect(get).toHaveBeenCalledWith('/api/v1/admin/blog/b-1');
    });

    it('پرسش‌های متداول و منابع و برچسب‌ها را هم نشان می‌دهد', async () => {
        renderWithProviders(<BlogReviewPage />, { route: '/admin/blog-review' });

        fireEvent.click(await screen.findByRole('button', { name: 'بازبینی' }));

        await waitFor(() => expect(screen.getByText('پرسش‌های متداول')).toBeInTheDocument());
        expect(screen.getByText('چند جلسه لازم است؟')).toBeInTheDocument();
        expect(screen.getByRole('link', { name: 'راهنمای پوست' })).toHaveAttribute('href', 'https://example.org/a');
        expect(screen.getByText('پوست')).toBeInTheDocument();
    });

    /** بازبین باید بداند چه چیزی را تأیید می‌کند: زمان مطالعه و کلیدواژه و موضوع. */
    it('شناسنامهٔ مقاله را بالای متن می‌آورد', async () => {
        renderWithProviders(<BlogReviewPage />, { route: '/admin/blog-review' });

        fireEvent.click(await screen.findByRole('button', { name: 'بازبینی' }));

        await waitFor(() => expect(screen.getByText('۷ دقیقه مطالعه')).toBeInTheDocument());
        expect(screen.getByText('کلیدواژه: لیزر موهای زائد')).toBeInTheDocument();
    });

    /** تا نیامدنِ متن، دکمه‌های تصمیم نباید روی یک قاب خالی بنشینند. */
    it('پیش از رسیدن متن، حالت بارگذاری نشان می‌دهد', async () => {
        get.mockImplementation((url: string) => {
            if (url.includes('/review-queue')) {
                return Promise.resolve({
                    success: true,
                    data: [ROW],
                    meta: { totalRecords: 1, totalPages: 1, currentPage: 1 },
                    errors: [],
                });
            }
            return new Promise(() => {});   // هرگز resolve نمی‌شود
        });

        renderWithProviders(<BlogReviewPage />, { route: '/admin/blog-review' });
        fireEvent.click(await screen.findByRole('button', { name: 'بازبینی' }));

        expect(await screen.findByText('در حال بارگذاری مقاله...')).toBeInTheDocument();
    });
});
