import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount, flushPromises } from '@vue/test-utils';
import { createVuetify } from 'vuetify';
import AdminIncidentsView from '../../resources/js/views/admin/AdminIncidentsView.vue';
import type { ApiAdminIncident } from '../../resources/js/api/admin';

vi.mock('../../resources/js/api/admin', async (importOriginal) => {
    const orig = await importOriginal<typeof import('../../resources/js/api/admin')>();
    return {
        ...orig,
        listAdminIncidents: vi.fn(),
    };
});

const adminApi = await import('../../resources/js/api/admin');

beforeEach(() => {
    vi.clearAllMocks();
});

function makeApiIncident(overrides: Partial<ApiAdminIncident> = {}): ApiAdminIncident {
    return {
        id: 1,
        incident_id: 'INC-2026-0509-0001',
        type: 'service_outage',
        severity: 'medium',
        summary: 'Test incident',
        started_at: new Date().toISOString(),
        detected_at: new Date().toISOString(),
        resolved_at: null,
        status: 'investigating',
        affected_tenants_count: 0,
        affected_users_count: null,
        rkn_notified: false,
        rkn_notified_at: null,
        rkn_deadline_at: null,
        ...overrides,
    };
}

const mountView = () =>
    mount(AdminIncidentsView, {
        global: { plugins: [createVuetify()] },
    });

describe('AdminIncidentsView ↔ GET /api/admin/incidents integration', () => {
    it('listAdminIncidents вызывается на mount', async () => {
        vi.mocked(adminApi.listAdminIncidents).mockResolvedValueOnce({
            incidents: [],
            total: 0,
            limit: 100,
            offset: 0,
            summary: { open: 0, investigating: 0, rkn_pending: 0, total_unresolved: 0 },
        });

        mountView();
        await flushPromises();
        expect(adminApi.listAdminIncidents).toHaveBeenCalledTimes(1);
    });

    it('успех — replace rowsState + summary', async () => {
        vi.mocked(adminApi.listAdminIncidents).mockResolvedValueOnce({
            incidents: [
                makeApiIncident({
                    id: 100,
                    type: 'data_breach',
                    severity: 'critical',
                    summary: 'PDN leak',
                    rkn_notified: false,
                    rkn_deadline_at: '2026-05-10T00:00:00Z',
                }),
                makeApiIncident({
                    id: 101,
                    type: 'service_outage',
                    summary: 'API timeout',
                    status: 'investigating',
                }),
            ],
            total: 2,
            limit: 100,
            offset: 0,
            summary: { open: 0, investigating: 2, rkn_pending: 1, total_unresolved: 2 },
        });

        const wrapper = mountView();
        await flushPromises();

        const vm = wrapper.vm as unknown as {
            rowsState: Array<{ id: number; title: string; category: string; rkn_deadline_at: string | null }>;
            stats: { open: number; investigating: number; rkn_pending: number };
        };
        expect(vm.rowsState).toHaveLength(2);
        expect(vm.rowsState[0].title).toBe('PDN leak');
        expect(vm.rowsState[0].category).toBe('data_breach');
        expect(vm.rowsState[0].rkn_deadline_at).toBe('2026-05-10T00:00:00Z');
        expect(vm.stats.investigating).toBe(2);
        expect(vm.stats.rkn_pending).toBe(1);
    });

    it('reject → fetchError=true + alert виден + rowsState пустой', async () => {
        vi.mocked(adminApi.listAdminIncidents).mockRejectedValueOnce(new Error('500'));

        const wrapper = mountView();
        await flushPromises();

        const vm = wrapper.vm as unknown as { fetchError: boolean; rowsState: unknown[] };
        expect(vm.fetchError).toBe(true);
        expect(vm.rowsState.length).toBe(0);
        expect(wrapper.find('[data-testid="fetch-error-alert"]').exists()).toBe(true);
    });

    it('reload-btn вызывает listAdminIncidents второй раз', async () => {
        vi.mocked(adminApi.listAdminIncidents).mockResolvedValue({
            incidents: [],
            total: 0,
            limit: 100,
            offset: 0,
            summary: { open: 0, investigating: 0, rkn_pending: 0, total_unresolved: 0 },
        });

        const wrapper = mountView();
        await flushPromises();
        expect(adminApi.listAdminIncidents).toHaveBeenCalledTimes(1);

        await wrapper.find('[data-testid="reload-btn"]').trigger('click');
        await flushPromises();
        expect(adminApi.listAdminIncidents).toHaveBeenCalledTimes(2);
    });

    it('РКН pending chip виден для data_breach без rkn_notified', async () => {
        vi.mocked(adminApi.listAdminIncidents).mockResolvedValueOnce({
            incidents: [
                makeApiIncident({
                    id: 200,
                    type: 'data_breach',
                    summary: 'breach',
                    rkn_notified: false,
                }),
            ],
            total: 1,
            limit: 100,
            offset: 0,
            summary: { open: 0, investigating: 1, rkn_pending: 1, total_unresolved: 1 },
        });

        const wrapper = mountView();
        await flushPromises();
        expect(wrapper.text()).toContain('РКН pending');
    });
});
