<script setup lang="ts">
/**
 * Диалог редактирования system_setting (двухстадийное подтверждение + audit-log).
 *
 * Step 1 «edit»: новое значение + reason ≥30 chars + кнопка «Далее».
 * Step 2 «confirm»: показ before/after + ещё раз подтверждение.
 *
 * На submit → PUT /api/admin/system-settings/{key} (audit-log пишется
 * автоматически на backend). На success — emit('updated') чтобы parent
 * перезагрузил список.
 */
import * as adminApi from '../../api/admin';
import { extractErrorMessage, extractValidationErrors } from '../../api/client';
import { computed, ref, watch } from 'vue';

const props = defineProps<{
    modelValue: boolean;
    setting: adminApi.SystemSetting | null;
    requestedBy: number;
}>();

const emit = defineEmits<{
    (e: 'update:modelValue', value: boolean): void;
    (e: 'updated', payload: adminApi.UpdateSystemSettingResponse): void;
}>();

type Step = 'edit' | 'confirm' | 'done';

const step = ref<Step>('edit');
const newValue = ref('');
const reason = ref('');
const valueError = ref<string | null>(null);
const reasonError = ref<string | null>(null);
const errorMessage = ref<string | null>(null);
const busy = ref(false);

const dialogOpen = computed({
    get: () => props.modelValue,
    set: (v) => emit('update:modelValue', v),
});

const reasonValid = computed(() => reason.value.trim().length >= 30);
const reasonRemaining = computed(() => Math.max(0, 30 - reason.value.trim().length));

function reset() {
    step.value = 'edit';
    newValue.value = props.setting?.value ?? '';
    reason.value = '';
    valueError.value = null;
    reasonError.value = null;
    errorMessage.value = null;
    busy.value = false;
}

watch(
    () => props.modelValue,
    (open) => {
        if (open) reset();
    },
    { immediate: true },
);

function goConfirm() {
    valueError.value = null;
    reasonError.value = null;
    if (props.setting && newValue.value === props.setting.value) {
        valueError.value = 'Новое значение совпадает со старым.';
        return;
    }
    if (!reasonValid.value) {
        reasonError.value = 'Минимум 30 символов.';
        return;
    }
    step.value = 'confirm';
}

async function submit() {
    if (!props.setting) return;
    busy.value = true;
    errorMessage.value = null;
    try {
        const r = await adminApi.updateSystemSetting(props.setting.key, {
            value: newValue.value,
            reason: reason.value.trim(),
            admin_user_id: props.requestedBy,
        });
        emit('updated', r);
        step.value = 'done';
    } catch (err) {
        const validation = extractValidationErrors(err);
        if (validation?.value?.[0]) {
            valueError.value = validation.value[0];
            step.value = 'edit';
        } else if (validation?.reason?.[0]) {
            reasonError.value = validation.reason[0];
            step.value = 'edit';
        } else {
            errorMessage.value = extractErrorMessage(err, 'Не удалось обновить настройку.');
        }
    } finally {
        busy.value = false;
    }
}

function close() {
    dialogOpen.value = false;
}

defineExpose({ step, newValue, reason, valueError, reasonError });
</script>

<template>
    <v-dialog v-model="dialogOpen" :max-width="540" persistent data-testid="system-setting-edit-dialog">
        <v-card v-if="setting">
            <v-card-title class="d-flex align-center">
                <v-icon class="me-2" color="warning">mdi-cog-outline</v-icon>
                Изменить настройку
            </v-card-title>
            <v-card-subtitle class="pb-2">
                <span class="font-mono">{{ setting.key }}</span>
                <v-chip class="ml-2" size="x-small" variant="tonal">{{ setting.type }}</v-chip>
            </v-card-subtitle>

            <v-card-text>
                <v-alert
                    v-if="errorMessage"
                    type="error"
                    variant="tonal"
                    density="compact"
                    class="mb-3"
                    data-testid="error-alert"
                >
                    {{ errorMessage }}
                </v-alert>

                <!-- STEP 1: edit -->
                <template v-if="step === 'edit'">
                    <v-alert type="warning" variant="tonal" density="compact" class="mb-3">
                        Изменение настройки будет записано в <code>saas_admin_audit_log</code> и попадёт в журнал
                        SaaS-админов. Действия неотменяемы — только новое изменение.
                    </v-alert>
                    <p class="text-body-2 text-medium-emphasis mb-3">{{ setting.description }}</p>
                    <div class="text-caption text-medium-emphasis mb-1">Текущее значение:</div>
                    <div class="value-block font-mono mb-3">{{ setting.value }}</div>
                    <v-text-field
                        v-model="newValue"
                        label="Новое значение"
                        variant="outlined"
                        density="comfortable"
                        :error-messages="valueError ? [valueError] : []"
                        data-testid="value-input"
                    />
                    <v-textarea
                        v-model="reason"
                        label="Основание (≥30 символов)"
                        variant="outlined"
                        rows="3"
                        :counter="200"
                        :error-messages="reasonError ? [reasonError] : []"
                        :hint="reasonValid ? 'Готово' : `Ещё ${reasonRemaining} символов`"
                        persistent-hint
                        placeholder="Решение CTO от 09.05.2026: ослабляем лимит для UX тестирования."
                        data-testid="reason-input"
                    />
                </template>

                <!-- STEP 2: confirm -->
                <template v-else-if="step === 'confirm'">
                    <v-alert type="info" variant="tonal" density="compact" class="mb-3">
                        Подтвердите изменение. После «Применить» backend обновит настройку и запишет в audit-log.
                    </v-alert>
                    <div class="diff-block">
                        <div class="diff-row">
                            <div class="diff-label text-caption text-medium-emphasis">Было:</div>
                            <div class="value-block font-mono diff-before">{{ setting.value }}</div>
                        </div>
                        <div class="diff-row">
                            <div class="diff-label text-caption text-medium-emphasis">Станет:</div>
                            <div class="value-block font-mono diff-after">{{ newValue }}</div>
                        </div>
                        <div class="diff-row">
                            <div class="diff-label text-caption text-medium-emphasis">Основание:</div>
                            <div class="reason-block">{{ reason.trim() }}</div>
                        </div>
                    </div>
                </template>

                <!-- STEP 3: done -->
                <template v-else-if="step === 'done'">
                    <v-alert type="success" variant="tonal" density="compact">
                        Настройка обновлена и записана в audit-log.
                    </v-alert>
                </template>
            </v-card-text>

            <v-card-actions>
                <v-spacer />
                <template v-if="step === 'edit'">
                    <v-btn variant="text" :disabled="busy" data-testid="cancel-btn" @click="close">Отмена</v-btn>
                    <v-btn color="primary" data-testid="next-btn" @click="goConfirm">Далее</v-btn>
                </template>
                <template v-else-if="step === 'confirm'">
                    <v-btn variant="text" :disabled="busy" data-testid="back-btn" @click="step = 'edit'">Назад</v-btn>
                    <v-btn color="primary" :loading="busy" data-testid="submit-btn" @click="submit"> Применить </v-btn>
                </template>
                <template v-else>
                    <v-btn color="primary" data-testid="close-btn" @click="close">Закрыть</v-btn>
                </template>
            </v-card-actions>
        </v-card>
    </v-dialog>
</template>

<style scoped>
.font-mono {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-feature-settings: 'tnum';
}
.value-block {
    background: #f6f3ec;
    padding: 6px 10px;
    border-radius: 4px;
    font-size: 13px;
    word-break: break-all;
}
.diff-block {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.diff-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.diff-before {
    background: #fde8e8;
    color: #842029;
    text-decoration: line-through;
}
.diff-after {
    background: #d8f1e6;
    color: #0a4029;
}
.reason-block {
    background: #fff8e6;
    padding: 8px 12px;
    border-radius: 4px;
    font-size: 13px;
    border-left: 3px solid #b88a00;
}
</style>
