<template>
    <div class="admin-pricing-tiers-view">
        <h1 class="text-h4 mb-6">Тарифная сетка</h1>

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

        <v-card class="mb-6" elevation="1">
            <v-card-title>
                Текущая активная сетка
                <span v-if="active.length" class="text-caption text-medium-emphasis ml-2">
                    (с {{ fmtEffective(active[0]?.effective_from) }})
                </span>
            </v-card-title>
            <v-data-table
                :headers="tierHeaders"
                :items="active"
                :items-per-page="7"
                density="comfortable"
                class="numeric-tnum"
            >
                <template #[`item.leads_in_tier`]="{ item }">
                    <span v-if="item.leads_in_tier !== null">{{ item.leads_in_tier }}</span>
                    <span v-else class="text-medium-emphasis">все свыше</span>
                </template>
                <template #[`item.price_rub`]="{ item }">
                    {{ fmtRub(item.price_per_lead_kopecks) }}
                </template>
            </v-data-table>
        </v-card>

        <v-card v-if="hasScheduled" class="mb-6" elevation="1">
            <v-card-title>Запланированные изменения</v-card-title>
            <v-card-text>
                <div v-for="(group, date) in scheduled" :key="date" class="mb-4">
                    <strong>С {{ date }}:</strong>
                    <v-data-table :headers="tierHeaders" :items="group" density="compact" class="mt-2" />
                    <v-btn color="error" variant="text" @click="confirmDelete(date)">Отменить</v-btn>
                </div>
            </v-card-text>
        </v-card>

        <v-btn color="primary" prepend-icon="mdi-pencil" data-testid="open-editor-btn" @click="openEditor">
            Редактировать сетку (с {{ nextMonthStart }})
        </v-btn>

        <v-dialog v-model="editorOpen" max-width="900">
            <v-card>
                <v-card-title>Новая сетка (effective_from = {{ effectiveFrom }})</v-card-title>
                <v-card-text>
                    <v-text-field
                        v-model="effectiveFrom"
                        type="date"
                        label="Дата вступления в силу"
                        :min="minEffectiveFrom"
                        density="compact"
                        class="mb-3"
                        style="max-width: 240px"
                        data-testid="effective-from-input"
                    />
                    <table class="editor-table">
                        <thead>
                            <tr>
                                <th>Ступень</th>
                                <th>Лидов в ступени</th>
                                <th>Цена за лид (₽)</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="t in editor" :key="t.tier_no">
                                <td>{{ t.tier_no }}</td>
                                <td>
                                    <v-text-field
                                        v-if="t.tier_no !== 7"
                                        v-model.number="t.leads_in_tier"
                                        type="number"
                                        min="1"
                                        density="compact"
                                        hide-details
                                    />
                                    <span v-else class="text-medium-emphasis">все свыше</span>
                                </td>
                                <td>
                                    <v-text-field
                                        v-model="t.price_rub"
                                        type="number"
                                        step="0.01"
                                        min="0"
                                        density="compact"
                                        hide-details
                                    />
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </v-card-text>
                <v-card-actions>
                    <v-spacer />
                    <v-btn @click="editorOpen = false">Отмена</v-btn>
                    <v-btn color="primary" :loading="saving" @click="submit">Сохранить</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>

        <v-dialog v-model="deleteDialogOpen" max-width="440">
            <v-card>
                <v-card-title>Удалить запланированный набор?</v-card-title>
                <v-card-text>
                    Запланированная сетка с <strong>{{ deleteTarget }}</strong> будет удалена. Действие необратимо.
                </v-card-text>
                <v-card-actions>
                    <v-spacer />
                    <v-btn @click="deleteDialogOpen = false">Отмена</v-btn>
                    <v-btn color="error" data-testid="confirm-delete-btn" @click="performDelete">Удалить</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>

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

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

/**
 * SaaS-admin → Тарифная сетка (Plan 4 Task 9, Sprint 1 G1 error handling).
 *
 * Backend: AdminPricingTiersController (GET/POST/DELETE).
 * Палитра Forest + JetBrains Mono для tnum-цифр.
 *
 * defineExpose ниже — для Vitest unit-тестов.
 */

const active = ref<AdminPricingTier[]>([]);
const scheduled = ref<Record<string, AdminPricingTier[]>>({});

// UI-аудит: epoch-дата (1970) выглядит сломанной → «начала»; ru-формат даты и цены.
function fmtEffective(iso?: string | null): string {
    if (!iso || iso.startsWith('1970')) return 'начала';
    return new Date(iso).toLocaleDateString('ru-RU');
}
function fmtRub(kopecks: number): string {
    return new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 2 }).format(kopecks / 100) + ' ₽';
}
const editorOpen = ref(false);
const saving = ref(false);

// Sprint 1 G1: error/success state для UI feedback.
const errorMessage = ref<string | null>(null);
const successMessage = ref<string | null>(null);
const successToastOpen = ref(false);

// G10: диалог подтверждения удаления (замена window.confirm).
const deleteDialogOpen = ref(false);
const deleteTarget = ref<string | null>(null);

const defaultEditor: PricingTierEditorRow[] = [
    { tier_no: 1, leads_in_tier: 100, price_rub: '500.00' },
    { tier_no: 2, leads_in_tier: 200, price_rub: '450.00' },
    { tier_no: 3, leads_in_tier: 400, price_rub: '400.00' },
    { tier_no: 4, leads_in_tier: 800, price_rub: '350.00' },
    { tier_no: 5, leads_in_tier: 1500, price_rub: '300.00' },
    { tier_no: 6, leads_in_tier: 3000, price_rub: '270.00' },
    { tier_no: 7, leads_in_tier: null, price_rub: '250.00' },
];
const editor = ref<PricingTierEditorRow[]>(JSON.parse(JSON.stringify(defaultEditor)));

const tierHeaders = [
    { title: '№', key: 'tier_no', sortable: false, width: 80 },
    { title: 'Лидов в ступени', key: 'leads_in_tier', sortable: false },
    { title: 'Цена за лид', key: 'price_rub', sortable: false },
];

const nextMonthStart = computed(() => {
    const d = new Date();
    d.setDate(1);
    d.setMonth(d.getMonth() + 1);
    return d.toISOString().slice(0, 10);
});

const effectiveFrom = ref<string>(nextMonthStart.value);

const minEffectiveFrom = computed(() => {
    // Минимум — сегодня (владелец может сменить тариф текущей датой; backend
    // валидирует after_or_equal:today). Прошлое по-прежнему недоступно.
    return new Date().toISOString().slice(0, 10);
});

const hasScheduled = computed(() => Object.keys(scheduled.value).length > 0);

async function load(): Promise<void> {
    try {
        const data = await getPricingTiers();
        active.value = data.active;
        scheduled.value = data.scheduled;
    } catch (err) {
        errorMessage.value = extractErrorMessage(err, 'Не удалось загрузить тарифную сетку.');
    }
}

async function submit(): Promise<void> {
    saving.value = true;
    errorMessage.value = null;
    successMessage.value = null;
    try {
        await createPricingTiers(editor.value, effectiveFrom.value);
        editorOpen.value = false;
        successMessage.value = `Сохранено: новая сетка вступит в силу с ${effectiveFrom.value}.`;
        successToastOpen.value = true;
        await load();
    } catch (err) {
        errorMessage.value = extractErrorMessage(err, 'Не удалось сохранить тарифную сетку.');
        // Диалог остаётся открытым — пользователь может исправить и повторить.
    } finally {
        saving.value = false;
    }
}

function openEditor(): void {
    effectiveFrom.value = nextMonthStart.value;
    editorOpen.value = true;
}

function confirmDelete(effectiveFromDate: string): void {
    deleteTarget.value = effectiveFromDate;
    deleteDialogOpen.value = true;
}

async function performDelete(): Promise<void> {
    const effectiveFromDate = deleteTarget.value;
    if (effectiveFromDate === null) return;
    deleteDialogOpen.value = false;
    errorMessage.value = null;
    successMessage.value = null;
    try {
        await deleteScheduledPricingTier(effectiveFromDate);
        successMessage.value = `Удалено: запланированный набор с ${effectiveFromDate}.`;
        successToastOpen.value = true;
        await load();
    } catch (err) {
        errorMessage.value = extractErrorMessage(err, 'Не удалось удалить запланированный набор.');
    } finally {
        deleteTarget.value = null;
    }
}

onMounted(load);

defineExpose({
    load,
    submit,
    openEditor,
    confirmDelete,
    performDelete,
    editorOpen,
    active,
    scheduled,
    editor,
    errorMessage,
    successMessage,
    successToastOpen,
    saving,
    effectiveFrom,
    deleteDialogOpen,
    deleteTarget,
});
</script>

<style scoped>
.numeric-tnum :deep(td) {
    font-feature-settings: 'tnum';
    font-family: 'JetBrains Mono', monospace;
}
.editor-table {
    width: 100%;
    border-collapse: collapse;
}
.editor-table th,
.editor-table td {
    padding: 8px 12px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
</style>
