<script setup lang="ts">
/**
 * Виджет Yandex SmartCaptcha (M-2). v-model = строка-токен.
 *
 * sitekey задан (VITE_YANDEX_SMARTCAPTCHA_SITEKEY) → реальный виджет:
 * подгружает captcha.js, рендерит через window.smartCaptcha.render, токен
 * приходит в callback → emit. reset() — сброс после ошибки регистрации
 * (одноразовый токен Yandex живёт 5 мин и используется однократно).
 *
 * sitekey пуст (dev/local/CI) → fallback на чекбокс «не робот» со стаб-токеном,
 * чтобы без ключа окружение и существующие сценарии не падали.
 *
 * Интеграция сверена по докам Yandex SmartCaptcha (advanced method, render=onload).
 */
import { onMounted, onUnmounted, ref } from 'vue';

defineProps<{
    modelValue: string;
    errorMessages?: string[];
}>();

const emit = defineEmits<{
    'update:modelValue': [token: string];
}>();

const sitekey = import.meta.env.VITE_YANDEX_SMARTCAPTCHA_SITEKEY ?? '';
const useReal = sitekey !== '';

const container = ref<HTMLElement | null>(null);
const widgetId = ref<number | null>(null);
const fallbackChecked = ref(false);

const SCRIPT_ID = 'yandex-smartcaptcha-js';
const SCRIPT_SRC = 'https://smartcaptcha.cloud.yandex.ru/captcha.js?render=onload&onload=__lidSmartCaptchaOnload';

function renderWidget(): void {
    if (!window.smartCaptcha || container.value === null || widgetId.value !== null) {
        return;
    }
    widgetId.value = window.smartCaptcha.render(container.value, {
        sitekey,
        hl: 'ru',
        callback: (token: string) => emit('update:modelValue', token),
    });
}

function loadAndRender(): void {
    if (window.smartCaptcha) {
        renderWidget();
        return;
    }
    window.__lidSmartCaptchaOnload = renderWidget;
    if (document.getElementById(SCRIPT_ID) === null) {
        const script = document.createElement('script');
        script.id = SCRIPT_ID;
        script.src = SCRIPT_SRC;
        script.defer = true;
        document.head.appendChild(script);
    }
}

function onFallbackChange(value: boolean | null): void {
    fallbackChecked.value = value === true;
    emit('update:modelValue', fallbackChecked.value ? 'dev-captcha-stub' : '');
}

/** Сброс капчи после ошибки регистрации — нужен свежий токен. */
function reset(): void {
    if (useReal) {
        if (window.smartCaptcha && widgetId.value !== null) {
            window.smartCaptcha.reset(widgetId.value);
        }
    } else {
        fallbackChecked.value = false;
    }
    emit('update:modelValue', '');
}

defineExpose({ reset });

onMounted(() => {
    if (useReal) {
        loadAndRender();
    }
});

onUnmounted(() => {
    if (useReal && window.smartCaptcha?.destroy && widgetId.value !== null) {
        window.smartCaptcha.destroy(widgetId.value);
    }
});
</script>

<template>
    <div class="smart-captcha">
        <div v-if="useReal" ref="container" class="smart-captcha__widget" />

        <v-checkbox
            v-else
            :model-value="fallbackChecked"
            density="compact"
            hide-details
            color="primary"
            :error-messages="errorMessages"
            @update:model-value="onFallbackChange"
        >
            <template #label>
                <span class="text-body-2">Подтвердите, что вы не робот</span>
            </template>
        </v-checkbox>
    </div>
</template>

<style scoped>
.smart-captcha__widget {
    min-height: 100px;
}
</style>
