<script setup lang="ts">
/**
 * Settings → API и Webhook (audit D2/D3/D4/D5 + J5).
 *
 * API-ключ: GET /api/api-keys показывает key_prefix; «Копировать» — clipboard
 *   + toast; «Перегенерировать» — POST /api/api-keys/regenerate, полный ключ
 *   показывается ОДИН раз (затем доступен только префикс).
 * Webhook: GET/PUT /api/tenants/me/webhook-settings (target_url + secret_prefix),
 *   «Тестовый webhook» — POST /api/webhooks/test (реальный unsigned POST).
 *
 * Полный ключ и полный секрет показываются один раз — в БД только bcrypt-хэши.
 * Подписанная outbound-доставка событий — пост-MVP.
 */
import { onMounted, ref } from 'vue';
import { listApiKeys, regenerateApiKey } from '../../api/apiKeys';
import { getWebhookSettings, saveWebhookSettings, testWebhook } from '../../api/webhooks';
import { extractErrorMessage } from '../../api/client';

// --- API-ключ ---
const apiKeyExists = ref(false);
const apiTokenDisplay = ref('');
const fullKeyShown = ref(false);
const tokenVisible = ref(false);
const apiKeyError = ref<string | null>(null);
const regenDialogOpen = ref(false);
const regenerating = ref(false);

// --- Webhook ---
const webhookUrl = ref('');
const secretDisplay = ref('');
const fullSecretShown = ref(false);
const secretVisible = ref(false);
const webhookError = ref<string | null>(null);
const webhookSuccess = ref<string | null>(null);
const savingWebhook = ref(false);
const testingWebhook = ref(false);

// --- общий toast (D2 copy + D5 test) ---
const toastOpen = ref(false);
const toastText = ref('');
const toastColor = ref<'success' | 'error'>('success');

function showToast(text: string, color: 'success' | 'error' = 'success'): void {
    toastText.value = text;
    toastColor.value = color;
    toastOpen.value = true;
}

async function loadApiKey(): Promise<void> {
    apiKeyError.value = null;
    try {
        const keys = await listApiKeys();
        const active = keys[0];
        if (active) {
            apiKeyExists.value = true;
            apiTokenDisplay.value = active.key_prefix;
            fullKeyShown.value = false;
        } else {
            apiKeyExists.value = false;
            apiTokenDisplay.value = '';
        }
    } catch (err) {
        apiKeyError.value = extractErrorMessage(err, 'Не удалось загрузить API-ключ.');
    }
}

async function loadWebhook(): Promise<void> {
    webhookError.value = null;
    try {
        const settings = await getWebhookSettings();
        if (settings) {
            webhookUrl.value = settings.target_url;
            secretDisplay.value = settings.secret_prefix;
            fullSecretShown.value = false;
        }
    } catch (err) {
        webhookError.value = extractErrorMessage(err, 'Не удалось загрузить настройки webhook.');
    }
}

onMounted(() => {
    void loadApiKey();
    void loadWebhook();
});

async function copyToken(): Promise<void> {
    if (apiTokenDisplay.value === '') return;
    try {
        await navigator.clipboard.writeText(apiTokenDisplay.value);
        showToast('Скопировано в буфер обмена.', 'success');
    } catch {
        showToast('Не удалось скопировать — выделите и скопируйте вручную.', 'error');
    }
}

async function confirmRegenerate(): Promise<void> {
    regenerating.value = true;
    apiKeyError.value = null;
    try {
        const result = await regenerateApiKey();
        apiTokenDisplay.value = result.key;
        fullKeyShown.value = true;
        apiKeyExists.value = true;
        tokenVisible.value = true;
        regenDialogOpen.value = false;
    } catch (err) {
        apiKeyError.value = extractErrorMessage(err, 'Не удалось перегенерировать ключ.');
        regenDialogOpen.value = false;
    } finally {
        regenerating.value = false;
    }
}

async function saveWebhook(): Promise<void> {
    if (savingWebhook.value) return;
    savingWebhook.value = true;
    webhookError.value = null;
    webhookSuccess.value = null;
    try {
        const result = await saveWebhookSettings({ target_url: webhookUrl.value });
        if (result.secret) {
            secretDisplay.value = result.secret;
            fullSecretShown.value = true;
            secretVisible.value = true;
        } else {
            secretDisplay.value = result.secret_prefix;
        }
        webhookSuccess.value = 'Настройки webhook сохранены.';
    } catch (err) {
        webhookError.value = extractErrorMessage(err, 'Не удалось сохранить webhook.');
    } finally {
        savingWebhook.value = false;
    }
}

async function runWebhookTest(): Promise<void> {
    if (testingWebhook.value) return;
    testingWebhook.value = true;
    try {
        const result = await testWebhook();
        showToast(result.message, result.ok ? 'success' : 'error');
    } catch (err) {
        showToast(extractErrorMessage(err, 'Не удалось отправить тестовый запрос.'), 'error');
    } finally {
        testingWebhook.value = false;
    }
}
</script>

<template>
    <div class="tab-content">
        <h2 class="tab-title text-h6 mb-4">API и Webhook</h2>

        <v-card variant="outlined" class="pa-4 mb-4">
            <h3 class="text-subtitle-2 mb-3">API-ключ</h3>
            <p class="text-body-2 text-medium-emphasis mb-3">
                Используется для подписи запросов в публичный API CRM. После регенерации старый ключ перестаёт работать
                немедленно.
            </p>

            <v-alert
                v-if="apiKeyError"
                type="warning"
                variant="tonal"
                density="compact"
                class="mb-3"
                closable
                data-testid="api-key-error"
                @click:close="apiKeyError = null"
            >
                {{ apiKeyError }}
            </v-alert>
            <v-alert
                v-if="fullKeyShown"
                type="warning"
                variant="tonal"
                density="compact"
                class="mb-3"
                data-testid="api-key-once-notice"
            >
                Новый ключ показывается <strong>один раз</strong>. Скопируйте и сохраните его сейчас.
            </v-alert>

            <v-text-field
                :model-value="apiTokenDisplay"
                :type="tokenVisible ? 'text' : 'password'"
                :placeholder="apiKeyExists ? '' : 'Ключ ещё не создан — нажмите «Перегенерировать»'"
                readonly
                variant="outlined"
                density="comfortable"
                data-testid="api-key-field"
            >
                <template #append-inner>
                    <v-btn
                        :icon="tokenVisible ? 'mdi-eye-off' : 'mdi-eye'"
                        variant="text"
                        density="compact"
                        size="small"
                        :aria-label="tokenVisible ? 'Скрыть ключ' : 'Показать ключ'"
                        @click="tokenVisible = !tokenVisible"
                    />
                </template>
            </v-text-field>
            <div class="d-flex ga-2 mt-2">
                <v-btn
                    variant="outlined"
                    size="small"
                    prepend-icon="mdi-content-copy"
                    :disabled="!apiTokenDisplay"
                    data-testid="api-key-copy-btn"
                    @click="copyToken"
                >
                    Копировать
                </v-btn>
                <v-btn
                    variant="outlined"
                    size="small"
                    color="warning"
                    prepend-icon="mdi-refresh"
                    data-testid="api-key-regen-btn"
                    @click="regenDialogOpen = true"
                >
                    Перегенерировать
                </v-btn>
            </div>
        </v-card>

        <v-card variant="outlined" class="pa-4">
            <h3 class="text-subtitle-2 mb-3">Webhook для приёма лидов</h3>
            <p class="text-body-2 text-medium-emphasis mb-3">
                URL источника лидов отправляет POST с подписью HMAC-SHA256. Дедуп по
                <code>(tenant_id, source_crm_id)</code> в окне 24 ч (антифрод по phone — §10.8.1).
            </p>

            <v-alert
                v-if="webhookError"
                type="warning"
                variant="tonal"
                density="compact"
                class="mb-3"
                closable
                data-testid="webhook-error"
                @click:close="webhookError = null"
            >
                {{ webhookError }}
            </v-alert>
            <v-alert
                v-if="webhookSuccess"
                type="success"
                variant="tonal"
                density="compact"
                class="mb-3"
                closable
                data-testid="webhook-success"
                @click:close="webhookSuccess = null"
            >
                {{ webhookSuccess }}
            </v-alert>
            <v-alert
                v-if="fullSecretShown"
                type="warning"
                variant="tonal"
                density="compact"
                class="mb-3"
                data-testid="webhook-secret-once-notice"
            >
                Signing secret показывается <strong>один раз</strong>. Сохраните его в настройках вашего приёмника.
            </v-alert>

            <v-text-field
                v-model="webhookUrl"
                label="Endpoint URL"
                placeholder="https://..."
                variant="outlined"
                density="comfortable"
                data-testid="webhook-url-field"
            />
            <v-text-field
                :model-value="secretDisplay"
                :type="secretVisible ? 'text' : 'password'"
                label="Signing secret (HMAC)"
                :placeholder="secretDisplay ? '' : 'Появится после первого сохранения URL'"
                readonly
                variant="outlined"
                density="comfortable"
                data-testid="webhook-secret-field"
            >
                <template #append-inner>
                    <v-btn
                        :icon="secretVisible ? 'mdi-eye-off' : 'mdi-eye'"
                        variant="text"
                        density="compact"
                        size="small"
                        :aria-label="secretVisible ? 'Скрыть секрет' : 'Показать секрет'"
                        @click="secretVisible = !secretVisible"
                    />
                </template>
            </v-text-field>
            <div class="d-flex ga-2 mt-2">
                <v-btn
                    color="primary"
                    variant="flat"
                    size="small"
                    :loading="savingWebhook"
                    data-testid="webhook-save-btn"
                    @click="saveWebhook"
                >
                    Сохранить
                </v-btn>
                <v-btn
                    variant="outlined"
                    size="small"
                    prepend-icon="mdi-test-tube"
                    :loading="testingWebhook"
                    data-testid="webhook-test-btn"
                    @click="runWebhookTest"
                >
                    Тестовый webhook
                </v-btn>
            </div>
        </v-card>

        <v-dialog v-model="regenDialogOpen" :max-width="440" data-testid="regen-dialog">
            <v-card>
                <v-card-title>Перегенерация API-ключа</v-card-title>
                <v-card-text>
                    Текущий ключ перестанет работать немедленно. Все интеграции с ним нужно будет обновить. Продолжить?
                </v-card-text>
                <v-card-actions>
                    <v-spacer />
                    <v-btn variant="text" :disabled="regenerating" @click="regenDialogOpen = false">Отмена</v-btn>
                    <v-btn
                        color="warning"
                        variant="flat"
                        :loading="regenerating"
                        data-testid="regen-confirm-btn"
                        @click="confirmRegenerate"
                    >
                        Перегенерировать
                    </v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>

        <v-snackbar
            v-model="toastOpen"
            :timeout="4000"
            :color="toastColor"
            location="bottom right"
            data-testid="api-tab-toast"
        >
            {{ toastText }}
        </v-snackbar>
    </div>
</template>

<style scoped>
.tab-title {
    font-variation-settings: 'opsz' 18;
    letter-spacing: -0.005em;
}
</style>
