<script setup lang="ts">
/**
 * Импорт данных — загрузка CSV исторических лидов из crm.bp-gr.ru (ТЗ §6).
 *
 * Flow: выбрать файл → загрузить → polling прогресса → таблица результата.
 * Неизвестные статусы маппятся через UnknownStatusesDialog.
 */
import { computed, onMounted, onUnmounted, ref } from 'vue';
import {
    getImport,
    getUnknownStatuses,
    listImports,
    uploadImport,
    type ImportLogResource,
    type UnknownStatus,
} from '../api/imports';
import UnknownStatusesDialog from '../components/import/UnknownStatusesDialog.vue';

const file = ref<File | null>(null);
const dryRun = ref(false);
const uploading = ref(false);
const errorMessage = ref<string | null>(null);
const history = ref<ImportLogResource[]>([]);
const activeImport = ref<ImportLogResource | null>(null);
const unknownStatuses = ref<UnknownStatus[]>([]);
const wizardOpen = ref(false);

/** Интервал опроса прогресса активного импорта, мс. */
const POLL_INTERVAL_MS = 2000;

let pollTimer: ReturnType<typeof setInterval> | null = null;

const canUpload = computed(() => file.value !== null && !uploading.value);

// Русские подписи статусов импорта (не показываем юзеру сырой enum).
const IMPORT_STATUS_RU: Record<string, string> = {
    pending: 'В очереди',
    processing: 'Обрабатывается',
    done: 'Готово',
    completed: 'Готово',
    failed: 'Ошибка',
    cancelled: 'Отменён',
};
function importStatusLabel(s: string): string {
    return IMPORT_STATUS_RU[s] ?? s;
}
const isProcessing = computed(
    () => activeImport.value?.status === 'pending' || activeImport.value?.status === 'processing',
);

async function refreshHistory(): Promise<void> {
    try {
        history.value = await listImports();
    } catch {
        // история — не критично, тихо игнорируем
    }
}

async function refreshUnknown(): Promise<void> {
    try {
        unknownStatuses.value = await getUnknownStatuses();
    } catch {
        unknownStatuses.value = [];
    }
}

function stopPolling(): void {
    if (pollTimer !== null) {
        clearInterval(pollTimer);
        pollTimer = null;
    }
}

async function pollOnce(id: number): Promise<void> {
    try {
        activeImport.value = await getImport(id);
        if (!isProcessing.value) {
            stopPolling();
            await refreshHistory();
            await refreshUnknown();
        }
    } catch {
        stopPolling();
    }
}

function startPolling(id: number): void {
    stopPolling();
    pollTimer = setInterval(() => {
        void pollOnce(id);
    }, POLL_INTERVAL_MS);
}

async function submit(): Promise<void> {
    if (file.value === null) {
        return;
    }
    uploading.value = true;
    errorMessage.value = null;
    try {
        activeImport.value = await uploadImport(file.value, dryRun.value);
        startPolling(activeImport.value.id);
        file.value = null;
    } catch {
        errorMessage.value = 'Не удалось загрузить файл. Проверьте формат (CSV, до 10 МБ).';
    } finally {
        uploading.value = false;
    }
}

async function onWizardResolved(): Promise<void> {
    wizardOpen.value = false;
    await refreshUnknown();
}

onMounted(async () => {
    await refreshHistory();
    await refreshUnknown();
});

onUnmounted(stopPolling);
</script>

<template>
    <v-container fluid class="import-view pa-6">
        <header class="page-head mb-4">
            <h1 class="text-h4 mb-2">Импорт данных</h1>
            <p class="text-body-2 text-medium-emphasis ma-0">
                Перенос ваших исторических заявок. Формат — CSV-выгрузка (UTF-8).
            </p>
        </header>

        <v-alert
            v-if="unknownStatuses.length > 0"
            data-test="unknown-banner"
            type="warning"
            variant="tonal"
            class="mb-4"
        >
            Найдено {{ unknownStatuses.length }} неизвестных статусов воронки — замапьте вручную.
            <template #append>
                <v-btn size="small" variant="flat" @click="wizardOpen = true">Замапить</v-btn>
            </template>
        </v-alert>

        <v-card variant="outlined" class="pa-6 mb-6">
            <v-file-input
                v-model="file"
                label="CSV-файл выгрузки лидов"
                accept=".csv,text/csv"
                prepend-icon="mdi-database-import-outline"
                variant="outlined"
                density="comfortable"
                :disabled="uploading"
            />
            <v-checkbox
                v-model="dryRun"
                label="Пробный прогон (проверить файл без записи сделок)"
                density="compact"
                hide-details
            />
            <v-alert v-if="errorMessage" type="error" variant="tonal" class="mt-3">
                {{ errorMessage }}
            </v-alert>
            <div class="mt-4">
                <v-btn
                    data-test="upload-btn"
                    color="primary"
                    :loading="uploading"
                    :disabled="!canUpload"
                    @click="submit"
                >
                    Загрузить
                </v-btn>
            </div>
        </v-card>

        <v-card v-if="activeImport" variant="outlined" class="pa-6 mb-6">
            <h2 class="text-h6 mb-3">Текущий импорт — {{ activeImport.filename }}</h2>
            <v-progress-linear v-if="isProcessing" indeterminate color="primary" class="mb-3" />
            <div data-test="active-status" class="text-body-2">
                Статус: <strong>{{ importStatusLabel(activeImport.status) }}</strong>
            </div>
            <v-table v-if="!isProcessing" density="compact" class="mt-3">
                <tbody>
                    <tr>
                        <td>Добавлено</td>
                        <td>{{ activeImport.rows_added }}</td>
                    </tr>
                    <tr>
                        <td>Обновлено</td>
                        <td>{{ activeImport.rows_updated }}</td>
                    </tr>
                    <tr>
                        <td>Пропущено</td>
                        <td>{{ activeImport.rows_skipped }}</td>
                    </tr>
                    <tr>
                        <td>Неизвестных статусов</td>
                        <td>{{ activeImport.unknown_statuses_count }}</td>
                    </tr>
                </tbody>
            </v-table>
            <v-alert v-if="activeImport.status === 'failed'" type="error" variant="tonal" class="mt-3">
                {{ activeImport.error_message }}
            </v-alert>
        </v-card>

        <v-card variant="outlined" class="pa-6">
            <h2 class="text-h6 mb-3">История импортов</h2>
            <v-table v-if="history.length > 0" density="compact">
                <thead>
                    <tr>
                        <th>Файл</th>
                        <th>Статус</th>
                        <th>Добавлено</th>
                        <th>Обновлено</th>
                        <th>Пропущено</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="row in history" :key="row.id">
                        <td>{{ row.filename }}</td>
                        <td>{{ importStatusLabel(row.status) }}</td>
                        <td>{{ row.rows_added }}</td>
                        <td>{{ row.rows_updated }}</td>
                        <td>{{ row.rows_skipped }}</td>
                    </tr>
                </tbody>
            </v-table>
            <p v-else class="text-body-2 text-medium-emphasis ma-0">Импортов пока нет.</p>
        </v-card>

        <UnknownStatusesDialog v-model="wizardOpen" :statuses="unknownStatuses" @resolved="onWizardResolved" />
    </v-container>
</template>

<style scoped>
.import-view {
    max-width: 1100px;
}
</style>
