import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount, flushPromises } from '@vue/test-utils';
import { createVuetify } from 'vuetify';
import AdminBillingView from '../../resources/js/views/admin/AdminBillingView.vue';
import type { ApiAdminBillingTenant } 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,
        listAdminBilling: vi.fn(),
    };
});

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

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

function makeApiBillingTenant(overrides: Partial<ApiAdminBillingTenant> = {}): ApiAdminBillingTenant {
    return {
        id: 1,
        subdomain: 'test',
        organization_name: 'Test ООО',
        contact_email: 'admin@test.io',
        status: 'active',
        balance_rub: '14250.00',
        tariff_id: 1,
        tariff_name: 'Команда',
        mrr_rub: '990.00',
        monthly_topups_rub: '30000.00',
        monthly_charges_rub: '25400.00',
        last_payment_at: '2026-05-04T10:23:00Z',
        chargeback_unrecovered_rub: '0.00',
        ...overrides,
    };
}

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

describe('AdminBillingView ↔ GET /api/admin/billing integration', () => {
    it('listAdminBilling вызывается на mount', async () => {
        vi.mocked(adminApi.listAdminBilling).mockResolvedValueOnce({
            tenants: [],
            summary: {
                total_mrr_rub: '0',
                monthly_revenue_rub: '0',
                overdue_count: 0,
                refunds_count_30d: 0,
            },
        });

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

    it('успех — replace rowsState + summary; numbers конвертируются из string', async () => {
        vi.mocked(adminApi.listAdminBilling).mockResolvedValueOnce({
            tenants: [
                makeApiBillingTenant({ id: 100, organization_name: 'Окна Москва', balance_rub: '14250.50' }),
                makeApiBillingTenant({
                    id: 101,
                    organization_name: 'Просрочник',
                    balance_rub: '-200.00',
                    status: 'active',
                }),
            ],
            summary: {
                total_mrr_rub: '1248600.00',
                monthly_revenue_rub: '1318400.00',
                overdue_count: 5,
                refunds_count_30d: 3,
            },
        });

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

        const vm = wrapper.vm as unknown as {
            rowsState: Array<{ id: number; name: string; balance_rub: number; status: string }>;
            summary: { total_mrr_rub: number; overdue_count: number; refunds_count_30d: number };
        };
        expect(vm.rowsState).toHaveLength(2);
        expect(vm.rowsState[0].balance_rub).toBe(14250.5);
        expect(vm.rowsState[1].status).toBe('overdue'); // balance<0 → derive
        expect(vm.summary.total_mrr_rub).toBe(1248600);
        expect(vm.summary.overdue_count).toBe(5);
        expect(vm.summary.refunds_count_30d).toBe(3);
    });

    it('reject → fetchError=true + alert виден + rowsState пустой', async () => {
        vi.mocked(adminApi.listAdminBilling).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 вызывает listAdminBilling второй раз', async () => {
        vi.mocked(adminApi.listAdminBilling).mockResolvedValue({
            tenants: [],
            summary: {
                total_mrr_rub: '0',
                monthly_revenue_rub: '0',
                overdue_count: 0,
                refunds_count_30d: 0,
            },
        });

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

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