import { describe, it, expect, beforeEach, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import { createVuetify } from 'vuetify';
import { createMemoryHistory, createRouter } from 'vue-router';

vi.mock('../../resources/js/api/reminders', () => ({
    listReminders: vi.fn(),
    createReminder: vi.fn(),
    updateReminder: vi.fn(),
    completeReminder: vi.fn(),
    deleteReminder: vi.fn(),
}));

vi.mock('../../resources/js/api/client', () => ({
    apiClient: {},
    ensureCsrfCookie: vi.fn(),
    extractValidationErrors: vi.fn(() => null),
    extractErrorMessage: vi.fn(() => 'Произошла ошибка.'),
    extractRateLimitRetry: vi.fn(() => null),
}));

import * as remindersApi from '../../resources/js/api/reminders';
import RemindersView from '../../resources/js/views/RemindersView.vue';
import type { ApiReminder } from '../../resources/js/api/reminders';

const mockReminder = (id: number, overrides: Partial<ApiReminder> = {}): ApiReminder => ({
    id,
    deal_id: 100 + id,
    text: `Перезвонить #${id}`,
    remind_at: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
    completed_at: null,
    is_sent: false,
    sent_at: null,
    created_at: new Date().toISOString(),
    created_by: 1,
    assignee_id: null,
    creator_name: 'Иван Петров',
    ...overrides,
});

const factory = async (
    apiResp: { items: ApiReminder[]; counts: { active: number; today: number; upcoming: number; overdue: number } } = {
        items: [],
        counts: { active: 0, today: 0, upcoming: 0, overdue: 0 },
    },
) => {
    setActivePinia(createPinia());
    vi.mocked(remindersApi.listReminders).mockResolvedValue(apiResp);

    const router = createRouter({
        history: createMemoryHistory(),
        routes: [
            { path: '/reminders', component: RemindersView },
            { path: '/deals', component: { template: '<div>deals</div>' } },
        ],
    });
    await router.push('/reminders');
    await router.isReady();

    const wrapper = mount(RemindersView, {
        global: {
            plugins: [createVuetify(), router],
            stubs: { ReminderDialog: true },
        },
    });
    await new Promise((r) => setTimeout(r, 0));
    await wrapper.vm.$nextTick();
    return wrapper;
};

describe('RemindersView.vue', () => {
    beforeEach(() => vi.clearAllMocks());

    it('монтируется и содержит заголовок «Напоминания»', async () => {
        const wrapper = await factory();
        expect(wrapper.find('.page-title').text()).toBe('Напоминания');
    });

    it('содержит 4 tabs (Сегодня/Предстоит/Просрочено/Выполнено)', async () => {
        const wrapper = await factory();
        const text = wrapper.text();
        ['Сегодня', 'Предстоит', 'Просрочено', 'Выполнено'].forEach((label) => {
            expect(text).toContain(label);
        });
    });

    it('показывает counts на табах', async () => {
        const wrapper = await factory({
            items: [],
            counts: { active: 5, today: 2, upcoming: 2, overdue: 1 },
        });

        const todayTab = wrapper.find('[data-testid="tab-today"]');
        expect(todayTab.text()).toContain('2');
        const overdueTab = wrapper.find('[data-testid="tab-overdue"]');
        expect(overdueTab.text()).toContain('1');
    });

    it('при пустом списке показывает empty-state', async () => {
        const wrapper = await factory();
        expect(wrapper.find('[data-testid="reminders-empty"]').exists()).toBe(true);
    });

    it('рендерит список напоминаний', async () => {
        const wrapper = await factory({
            items: [mockReminder(1), mockReminder(2)],
            counts: { active: 2, today: 2, upcoming: 0, overdue: 0 },
        });

        const items = wrapper.findAll('[data-testid="reminder-item"]');
        expect(items).toHaveLength(2);
    });

    it('reload-btn вызывает listReminders повторно', async () => {
        const wrapper = await factory();
        const initialCalls = vi.mocked(remindersApi.listReminders).mock.calls.length;

        await wrapper.find('[data-testid="reload-btn"]').trigger('click');
        await wrapper.vm.$nextTick();

        expect(vi.mocked(remindersApi.listReminders).mock.calls.length).toBeGreaterThan(initialCalls);
    });

    it('listReminders вызывается с filter=today по умолчанию', async () => {
        await factory();
        expect(remindersApi.listReminders).toHaveBeenCalledWith(expect.objectContaining({ filter: 'today' }));
    });
});
