<template>
    <div class="admin-autopodbor-pricing-view">
        <h1 class="text-h4 mb-1">Тарифы и услуги «Конкурентного поля»</h1>
        <p class="text-body-2 text-medium-emphasis mb-6">Управление ценами. Изменения применяются ко всем клиентам.</p>

        <v-alert
            v-if="errorMessage"
            type="error"
            variant="tonal"
            density="compact"
            class="mb-4"
            closable
            data-testid="ap-pricing-error"
            @click:close="errorMessage = null"
        >
            {{ errorMessage }}
        </v-alert>

        <v-card class="mb-6" elevation="1" max-width="640">
            <v-card-title class="text-subtitle-1 font-weight-bold">Дополнительные услуги</v-card-title>
            <v-card-subtitle class="pb-2">Цена за успешный результат. Списывается только при успехе, пустой результат — бесплатно.</v-card-subtitle>
            <v-card-text>
                <v-text-field
                    v-model="searchPrice"
                    type="number"
                    min="0"
                    step="1"
                    label="Сбор конкурентов — ₽ за подбор"
                    hint="Списывается при успешном подборе конкурентов."
                    persistent-hint
                    density="comfortable"
                    class="mb-3"
                    data-testid="ap-search-price"
                />
                <v-text-field
                    v-model="studyPrice"
                    type="number"
                    min="0"
                    step="1"
                    label="Сбор источников — ₽ за изучение конкурента"
                    hint="Списывается, если нашли сайты/телефоны конкурента."
                    persistent-hint
                    density="comfortable"
                    class="mb-3"
                    data-testid="ap-study-price"
                />
                <v-textarea
                    v-model="reason"
                    label="Причина изменения (для журнала аудита) — минимум 30 символов"
                    :error="reason.length > 0 && !reasonValid"
                    rows="2"
                    auto-grow
                    density="comfortable"
                    data-testid="ap-reason"
                />
                <div class="d-flex justify-end">
                    <v-btn
                        color="primary"
                        :loading="saving"
                        :disabled="!hasChanges"
                        data-testid="ap-save-btn"
                        @click="save"
                    >
                        Сохранить тарифы
                    </v-btn>
                </div>
            </v-card-text>
        </v-card>

        <h2 class="text-subtitle-1 font-weight-bold mb-1">Тариф на лиды</h2>
        <p class="text-body-2 text-medium-emphasis mb-2">
            Сетка цен за лиды по объёму — здесь для справки (настраивается отдельно в «Тарифной сетке»).
        </p>
        <v-card elevation="1" max-width="640">
            <table class="lead-tiers-table">
                <thead>
                    <tr>
                        <th>Лидов в ступени</th>
                        <th class="r">Цена за лид</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="t in tiers" :key="t.tier_no">
                        <td>
                            <span v-if="t.leads_in_tier !== null">{{ t.leads_in_tier }}</span>
                            <span v-else class="text-medium-emphasis">все свыше</span>
                        </td>
                        <td class="r num">{{ fmtRub(t.price_per_lead_kopecks) }}</td>
                    </tr>
                </tbody>
            </table>
        </v-card>

        <v-snackbar
            v-model="successToastOpen"
            :timeout="4000"
            color="success"
            location="bottom right"
            data-testid="ap-pricing-success"
        >
            {{ successMessage }}
        </v-snackbar>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { listSystemSettings, updateSystemSetting, getPricingTiers, type AdminPricingTier } from '../../api/admin';
import { extractErrorMessage } from '../../api/client';

/**
 * SaaS-admin → дружелюбный экран тарифов доп.услуг «Конкурентного поля».
 * Правит две цены в system_settings (autopodbor_price_search_rub / _study_rub)
 * через PUT /api/admin/system-settings/{key} (audit-log, reason ≥30). Сетка лидов —
 * справочно (read-only). Прообраз — прототип renderAdmin.
 */

const SEARCH_KEY = 'autopodbor_price_search_rub';
const STUDY_KEY = 'autopodbor_price_study_rub';
const DEFAULT_REASON = 'Изменение тарифов доп.услуг «Конкурентное поле» администратором.';

const searchPrice = ref('');
const studyPrice = ref('');
const origSearch = ref('');
const origStudy = ref('');
const reason = ref(DEFAULT_REASON);

const tiers = ref<AdminPricingTier[]>([]);
const saving = ref(false);
const errorMessage = ref<string | null>(null);
const successMessage = ref<string | null>(null);
const successToastOpen = ref(false);

const reasonValid = computed(() => reason.value.trim().length >= 30);
const hasChanges = computed(
    () => searchPrice.value !== origSearch.value || studyPrice.value !== origStudy.value,
);

function fmtRub(kopecks: number): string {
    return new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 2 }).format(kopecks / 100) + ' ₽';
}

async function load(): Promise<void> {
    errorMessage.value = null;
    try {
        const settings = await listSystemSettings();
        const s = settings.find((x) => x.key === SEARCH_KEY);
        const t = settings.find((x) => x.key === STUDY_KEY);
        searchPrice.value = origSearch.value = s?.value ?? '';
        studyPrice.value = origStudy.value = t?.value ?? '';
    } catch (err) {
        errorMessage.value = extractErrorMessage(err, 'Не удалось загрузить тарифы.');
    }
    try {
        const data = await getPricingTiers();
        tiers.value = data.active;
    } catch {
        // Сетка лидов — справочная; её отсутствие не блокирует правку цен.
    }
}

async function save(): Promise<void> {
    errorMessage.value = null;
    successMessage.value = null;
    if (!hasChanges.value) {
        errorMessage.value = 'Вы не изменили ни одной цены.';
        return;
    }
    if (!reasonValid.value) {
        errorMessage.value = 'Укажите причину изменения — минимум 30 символов (для журнала аудита).';
        return;
    }
    saving.value = true;
    try {
        const reasonText = reason.value.trim();
        // admin_user_id НЕ шлём с клиента — бэкенд проставляет id админа из сессии (audit-log).
        if (searchPrice.value !== origSearch.value) {
            await updateSystemSetting(SEARCH_KEY, { value: String(searchPrice.value), reason: reasonText });
        }
        if (studyPrice.value !== origStudy.value) {
            await updateSystemSetting(STUDY_KEY, { value: String(studyPrice.value), reason: reasonText });
        }
        successMessage.value = 'Тарифы сохранены. Изменения применяются ко всем клиентам.';
        successToastOpen.value = true;
        await load();
    } catch (err) {
        errorMessage.value = extractErrorMessage(err, 'Не удалось сохранить тарифы.');
    } finally {
        saving.value = false;
    }
}

onMounted(load);

defineExpose({
    load,
    save,
    searchPrice,
    studyPrice,
    reason,
    tiers,
    saving,
    errorMessage,
    successMessage,
    successToastOpen,
    reasonValid,
    hasChanges,
});
</script>

<style scoped>
.lead-tiers-table {
    width: 100%;
    border-collapse: collapse;
}
.lead-tiers-table th,
.lead-tiers-table td {
    padding: 9px 16px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    text-align: left;
    font-size: 14px;
}
.lead-tiers-table th {
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #55606b;
}
.lead-tiers-table .r {
    text-align: right;
}
.lead-tiers-table .num {
    font-family: 'JetBrains Mono', monospace;
    font-feature-settings: 'tnum';
    font-weight: 600;
    color: #0f6e56;
}
</style>
