<template>
    <div class="admin-supplier-prices-view">
        <h1 class="text-h4 mb-6">Цены поставщиков (закупка)</h1>

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

        <v-card elevation="1">
            <v-data-table :headers="headers" :items="suppliers" density="comfortable" class="numeric-tnum">
                <template #[`item.cost_rub`]="{ item }">
                    <v-text-field
                        v-model="item.cost_rub"
                        type="number"
                        step="0.01"
                        min="0"
                        density="compact"
                        hide-details
                        variant="plain"
                        :aria-label="`Cost (₽) для ${item.name}`"
                    />
                </template>
                <template #[`item.quality_score`]="{ item }">
                    <v-text-field
                        v-model="item.quality_score"
                        type="number"
                        step="0.01"
                        min="0"
                        max="9.99"
                        density="compact"
                        hide-details
                        variant="plain"
                        :aria-label="`Quality для ${item.name}`"
                    />
                </template>
                <template #[`item.is_active`]="{ item }">
                    <v-switch
                        v-model="item.is_active"
                        hide-details
                        inset
                        density="compact"
                        :aria-label="`Active для ${item.name}`"
                    />
                </template>
                <template #[`item.actions`]="{ item }">
                    <div class="d-flex flex-column align-end ga-1">
                        <v-btn size="small" color="primary" :loading="!!saving[item.id]" @click="save(item)">
                            Сохранить
                        </v-btn>
                        <v-tooltip v-if="errorMessages[item.id]" location="left">
                            <template #activator="{ props: tooltipProps }">
                                <v-icon
                                    v-bind="tooltipProps"
                                    color="error"
                                    size="small"
                                    :data-testid="`supplier-error-${item.id}`"
                                >
                                    mdi-alert-circle
                                </v-icon>
                            </template>
                            <span>{{ errorMessages[item.id] }}</span>
                        </v-tooltip>
                    </div>
                </template>
            </v-data-table>
        </v-card>

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

<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue';
import { getAdminSuppliers, updateAdminSupplier, type AdminSupplier } from '../../api/admin';
import { extractErrorMessage } from '../../api/client';

/**
 * SaaS-admin → Цены поставщиков (Plan 4 Task 10, Sprint 1 G2 error handling).
 *
 * Backend: AdminSuppliersController (GET/PATCH).
 * Палитра Forest + JetBrains Mono для tnum-цифр.
 *
 * defineExpose ниже — для Vitest unit-тестов.
 */

const suppliers = ref<AdminSupplier[]>([]);
const saving = reactive<Record<number, boolean>>({});
const errorMessages = reactive<Record<number, string>>({});
const fetchError = ref<string | null>(null);
const successToastOpen = ref(false);
const successToastText = ref('');

const headers = [
    { title: 'Код', key: 'code', sortable: false, width: 80 },
    { title: 'Название', key: 'name', sortable: false },
    { title: 'Цена (₽)', key: 'cost_rub', sortable: false, width: 140 },
    { title: 'Качество', key: 'quality_score', sortable: false, width: 100 },
    { title: 'Активен', key: 'is_active', sortable: false, width: 100 },
    { title: 'Действия', key: 'actions', sortable: false, width: 120 },
];

async function load(): Promise<void> {
    fetchError.value = null;
    try {
        suppliers.value = await getAdminSuppliers();
    } catch (err) {
        fetchError.value = extractErrorMessage(err, 'Не удалось загрузить список поставщиков.');
    }
}

async function save(s: AdminSupplier): Promise<void> {
    saving[s.id] = true;
    delete errorMessages[s.id]; // очистить предыдущую ошибку перед retry
    try {
        await updateAdminSupplier(s.id, {
            cost_rub: s.cost_rub,
            quality_score: s.quality_score,
            is_active: s.is_active,
        });
        successToastText.value = `Сохранено: ${s.name} (${s.code}).`;
        successToastOpen.value = true;
    } catch (err) {
        errorMessages[s.id] = extractErrorMessage(err, 'Не удалось сохранить изменения.');
    } finally {
        saving[s.id] = false;
    }
}

onMounted(load);

defineExpose({ load, save, suppliers, saving, errorMessages, fetchError, successToastOpen, successToastText });
</script>

<style scoped>
.numeric-tnum :deep(td) {
    font-feature-settings: 'tnum';
    font-family: 'JetBrains Mono', monospace;
}
</style>
