import { mount } from '@vue/test-utils';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { createVuetify } from 'vuetify';

import TenantBalanceDialog from '../../resources/js/components/admin/TenantBalanceDialog.vue';
import * as adminApi from '../../resources/js/api/admin';

const vuetify = createVuetify();

function mountDialog(props: Record<string, unknown> = {}) {
    return mount(TenantBalanceDialog, {
        props: {
            modelValue: true,
            tenantId: 42,
            tenantName: 'Окна Москва ООО',
            currentBalanceRub: 1000,
            ...props,
        },
        global: { plugins: [vuetify] },
        attachTo: document.body,
    });
}

describe('TenantBalanceDialog', () => {
    beforeEach(() => {
        vi.restoreAllMocks();
    });

    it('previews signed delta when new balance entered', async () => {
        const w = mountDialog();
        (w.vm as unknown as { newBalance: string }).newBalance = '2500';
        await w.vm.$nextTick();
        expect((w.vm as unknown as { delta: string }).delta).toBe('1500.00');
    });

    it('disables save when balance empty or unchanged', async () => {
        const w = mountDialog();
        const vm = w.vm as unknown as { newBalance: string; canSave: boolean };
        vm.newBalance = '';
        await w.vm.$nextTick();
        expect((w.vm as unknown as { canSave: boolean }).canSave).toBe(false);
        vm.newBalance = '1000';
        await w.vm.$nextTick();
        expect((w.vm as unknown as { canSave: boolean }).canSave).toBe(false);
        vm.newBalance = '1500';
        await w.vm.$nextTick();
        expect((w.vm as unknown as { canSave: boolean }).canSave).toBe(true);
    });

    it('calls updateTenantBalance with normalized payload and emits saved', async () => {
        const spy = vi.spyOn(adminApi, 'updateTenantBalance').mockResolvedValue({
            id: 42,
            balance_rub: '2500.00',
            delta: '1500.00',
            transaction_id: 7,
        });
        const w = mountDialog();
        const vm = w.vm as unknown as { newBalance: string; reason: string; submit: () => Promise<void> };
        vm.newBalance = '2500';
        vm.reason = 'тест';
        await vm.submit();

        expect(spy).toHaveBeenCalledWith(42, { balance_rub: '2500.00', reason: 'тест' });
        expect(w.emitted('saved')).toBeTruthy();
        expect(w.emitted('saved')![0][0]).toMatchObject({ balance_rub: '2500.00' });
    });
});
