<script setup lang="ts">
/**
 * Диалог установки точного ₽-баланса тенанта (SaaS-admin).
 * Используется из карточки тенанта (TenantDetailHeader) и из строки таблицы
 * списка (TenantsTable). Семантика «установить точную сумму» — сервер сам
 * считает знаковую дельту и пишет manual_adjustment + audit.
 */
import { computed, ref, watch } from 'vue';
import { updateTenantBalance } from '../../api/admin';
import { extractErrorMessage } from '../../api/client';

const props = defineProps<{
    modelValue: boolean;
    tenantId: number;
    tenantName: string;
    currentBalanceRub: number;
}>();

const emit = defineEmits<{
    'update:modelValue': [value: boolean];
    saved: [payload: { balance_rub: string; delta: string; transaction_id: number }];
}>();

const newBalance = ref('');
const reason = ref('');
const submitting = ref(false);
const errorMsg = ref<string | null>(null);

const targetNormalized = computed(() => {
    const raw = newBalance.value.trim().replace(',', '.');
    if (!/^-?\d+(\.\d{1,2})?$/.test(raw)) return '';
    return Number(raw).toFixed(2);
});

const delta = computed(() => {
    if (targetNormalized.value === '') return '';
    return (Number(targetNormalized.value) - props.currentBalanceRub).toFixed(2);
});

const canSave = computed(
    () => !submitting.value && targetNormalized.value !== '' && delta.value !== '' && Number(delta.value) !== 0,
);

watch(
    () => props.modelValue,
    (open) => {
        if (open) {
            newBalance.value = '';
            reason.value = '';
            errorMsg.value = null;
        }
    },
);

async function submit(): Promise<void> {
    if (!canSave.value) return;
    submitting.value = true;
    errorMsg.value = null;
    try {
        const payload: { balance_rub: string; reason?: string } = { balance_rub: targetNormalized.value };
        if (reason.value.trim() !== '') payload.reason = reason.value.trim();
        const result = await updateTenantBalance(props.tenantId, payload);
        emit('saved', { balance_rub: result.balance_rub, delta: result.delta, transaction_id: result.transaction_id });
        emit('update:modelValue', false);
    } catch (e) {
        errorMsg.value = extractErrorMessage(e, 'Не удалось изменить баланс.');
    } finally {
        submitting.value = false;
    }
}

function close(): void {
    emit('update:modelValue', false);
}
</script>

<template>
    <v-dialog :model-value="modelValue" max-width="460" @update:model-value="emit('update:modelValue', $event)">
        <v-card>
            <v-card-title class="text-h6">Изменить баланс</v-card-title>
            <v-card-subtitle>{{ tenantName }}</v-card-subtitle>
            <v-card-text>
                <div class="text-body-2 text-medium-emphasis mb-3">
                    Текущий баланс: <strong class="num">{{ currentBalanceRub.toFixed(2) }} ₽</strong>
                </div>

                <v-text-field
                    v-model="newBalance"
                    label="Новый баланс, ₽"
                    type="text"
                    inputmode="decimal"
                    density="comfortable"
                    data-testid="balance-input"
                    :hint="targetNormalized === '' && newBalance !== '' ? 'Формат: 1234.56' : ''"
                    persistent-hint
                />

                <v-text-field
                    v-model="reason"
                    label="Причина (необязательно)"
                    type="text"
                    density="comfortable"
                    maxlength="500"
                    class="mt-2"
                    data-testid="reason-input"
                />

                <div v-if="delta !== ''" class="preview mt-3 text-body-2">
                    было <span class="num">{{ currentBalanceRub.toFixed(2) }} ₽</span> → станет
                    <span class="num">{{ targetNormalized }} ₽</span> (<span
                        class="num"
                        :class="Number(delta) < 0 ? 'text-error' : 'text-success'"
                    >
                        {{ Number(delta) > 0 ? '+' : '' }}{{ delta }} ₽ </span
                    >)
                </div>

                <v-alert v-if="errorMsg" type="error" variant="tonal" density="compact" class="mt-3">
                    {{ errorMsg }}
                </v-alert>
            </v-card-text>
            <v-card-actions>
                <v-spacer />
                <v-btn variant="text" :disabled="submitting" @click="close">Отмена</v-btn>
                <v-btn
                    color="primary"
                    variant="flat"
                    :loading="submitting"
                    :disabled="!canSave"
                    data-testid="balance-save"
                    @click="submit"
                >
                    Сохранить
                </v-btn>
            </v-card-actions>
        </v-card>
    </v-dialog>
</template>

<style scoped>
.num {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-feature-settings: 'tnum';
}
</style>
