<script setup lang="ts">
/**
 * Adminка SaaS → Обращения субъектов ПДн (152-ФЗ).
 *
 * Список обращений на удаление/доступ/исправление/возражение.
 * Для request_type='deletion' — кнопка «Анонимизировать» (§ 1.5, дыра #4).
 *
 * API: GET/POST /api/admin/pd-subject-requests, POST /{id}/erase
 */
import { onMounted, ref, reactive, computed } from 'vue';
import * as adminApi from '../../api/admin';
import type { PdSubjectRequest, CreatePdRequestPayload } from '../../api/admin';

// ---------------------------------------------------------------------------
// State
// ---------------------------------------------------------------------------
const rows = ref<PdSubjectRequest[]>([]);
const total = ref(0);
const loading = ref(false);
const fetchError = ref(false);

const filterStatus = ref('');
const filterType = ref('');

// Dialog: create
const createDialog = ref(false);
const createLoading = ref(false);
const createError = ref('');
const createForm = reactive<CreatePdRequestPayload>({
    subject_email: '',
    subject_phone: '',
    subject_full_name: '',
    request_type: 'deletion',
    description: '',
    tenant_id: null,
});

// Dialog: erase confirm
const eraseDialog = ref(false);
const eraseLoading = ref(false);
// UI-аудит: window.alert → v-snackbar.
const errToastOpen = ref(false);
const errToastText = ref('');
const eraseTarget = ref<PdSubjectRequest | null>(null);
const eraseResult = ref<{ users: number; leads: number; deals: number; webhook_log: number } | null>(null);

// ---------------------------------------------------------------------------
// Load data
// ---------------------------------------------------------------------------
async function loadRows(): Promise<void> {
    loading.value = true;
    fetchError.value = false;
    try {
        const res = await adminApi.listPdSubjectRequests({
            status: filterStatus.value || undefined,
            request_type: filterType.value || undefined,
            limit: 100,
            offset: 0,
        });
        rows.value = res.data;
        total.value = res.total;
    } catch {
        fetchError.value = true;
    } finally {
        loading.value = false;
    }
}

onMounted(loadRows);

// ---------------------------------------------------------------------------
// Create request
// ---------------------------------------------------------------------------
async function submitCreate(): Promise<void> {
    createError.value = '';
    if (!createForm.subject_email && !createForm.subject_phone) {
        createError.value = 'Укажите email или телефон субъекта.';
        return;
    }
    createLoading.value = true;
    try {
        await adminApi.createPdSubjectRequest({
            subject_email: createForm.subject_email || undefined,
            subject_phone: createForm.subject_phone || undefined,
            subject_full_name: createForm.subject_full_name || undefined,
            request_type: createForm.request_type,
            description: createForm.description || undefined,
            tenant_id: createForm.tenant_id ?? undefined,
        });
        createDialog.value = false;
        resetCreateForm();
        await loadRows();
    } catch (e: unknown) {
        const err = e as { response?: { data?: { message?: string } } };
        createError.value = err?.response?.data?.message ?? 'Ошибка при создании обращения.';
    } finally {
        createLoading.value = false;
    }
}

function resetCreateForm(): void {
    createForm.subject_email = '';
    createForm.subject_phone = '';
    createForm.subject_full_name = '';
    createForm.request_type = 'deletion';
    createForm.description = '';
    createForm.tenant_id = null;
    createError.value = '';
}

// ---------------------------------------------------------------------------
// Erase
// ---------------------------------------------------------------------------
function openErase(row: PdSubjectRequest): void {
    eraseTarget.value = row;
    eraseResult.value = null;
    eraseDialog.value = true;
}

async function confirmErase(): Promise<void> {
    if (!eraseTarget.value) return;
    eraseLoading.value = true;
    try {
        const res = await adminApi.executePdErasure(eraseTarget.value.id);
        eraseResult.value = res.counts;
        // Update row status in list
        const idx = rows.value.findIndex((r) => r.id === eraseTarget.value?.id);
        if (idx !== -1) {
            rows.value[idx] = { ...rows.value[idx], status: 'completed' };
        }
    } catch (e: unknown) {
        const err = e as { response?: { data?: { message?: string } } };
        errToastText.value = err?.response?.data?.message ?? 'Ошибка анонимизации.';
        errToastOpen.value = true;
        eraseDialog.value = false;
    } finally {
        eraseLoading.value = false;
    }
}

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
const statusLabels: Record<string, { label: string; color: string }> = {
    received: { label: 'Получено', color: 'info' },
    in_progress: { label: 'В работе', color: 'warning' },
    completed: { label: 'Выполнено', color: 'success' },
    rejected: { label: 'Отклонено', color: 'error' },
};
function statusInfo(s: string) {
    return statusLabels[s] ?? { label: s, color: 'default' };
}

const typeLabels: Record<string, string> = {
    access: 'Доступ',
    rectification: 'Исправление',
    deletion: 'Удаление',
    objection: 'Возражение',
};
function typeLabel(t: string): string {
    return typeLabels[t] ?? t;
}

function formatDate(iso: string | null): string {
    if (!iso) return '—';
    return new Date(iso).toLocaleString('ru-RU', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
        hour: '2-digit',
        minute: '2-digit',
    });
}

const headers = [
    { title: 'ID', key: 'id', width: '60px' },
    { title: 'Получено', key: 'received_at', width: '140px' },
    { title: 'Email / тел.', key: 'contact', sortable: false },
    { title: 'Тип', key: 'request_type', width: '110px' },
    { title: 'Статус', key: 'status', width: '120px' },
    { title: 'Дедлайн', key: 'deadline_at', width: '140px' },
    { title: 'Действия', key: 'actions', sortable: false, width: '140px', align: 'end' as const },
];

const filteredRows = computed(() => rows.value);

defineExpose({ rows, loading, fetchError, loadRows });
</script>

<template>
    <v-container fluid class="admin-pd pa-6">
        <!-- Page head -->
        <header class="page-head mb-4 d-flex justify-space-between align-start flex-wrap ga-3">
            <div>
                <h1 class="text-h4 page-title">Обращения субъектов ПДн</h1>
                <p class="text-body-2 text-medium-emphasis ma-0">
                    Обращения на доступ, исправление, удаление и возражение (152-ФЗ). Срок ответа — 30 дней.
                </p>
            </div>
            <div class="d-flex ga-2">
                <v-btn
                    variant="outlined"
                    prepend-icon="mdi-refresh"
                    :loading="loading"
                    data-testid="reload-btn"
                    @click="loadRows"
                >
                    Обновить
                </v-btn>
                <v-btn color="primary" prepend-icon="mdi-plus" data-testid="create-btn" @click="createDialog = true">
                    Новый запрос
                </v-btn>
            </div>
        </header>

        <v-alert
            v-if="fetchError"
            type="warning"
            variant="tonal"
            density="compact"
            closable
            class="mb-4"
            data-testid="fetch-error-alert"
        >
            Не удалось загрузить обращения. Попробуйте обновить.
        </v-alert>

        <!-- Filters -->
        <v-card variant="outlined" class="pa-3 mb-4">
            <v-row dense>
                <v-col cols="12" sm="4">
                    <v-select
                        v-model="filterStatus"
                        label="Статус"
                        :items="[
                            { title: 'Все статусы', value: '' },
                            { title: 'Получено', value: 'received' },
                            { title: 'В работе', value: 'in_progress' },
                            { title: 'Выполнено', value: 'completed' },
                            { title: 'Отклонено', value: 'rejected' },
                        ]"
                        density="compact"
                        variant="outlined"
                        hide-details
                        @update:model-value="loadRows"
                    />
                </v-col>
                <v-col cols="12" sm="4">
                    <v-select
                        v-model="filterType"
                        label="Тип обращения"
                        :items="[
                            { title: 'Все типы', value: '' },
                            { title: 'Доступ', value: 'access' },
                            { title: 'Исправление', value: 'rectification' },
                            { title: 'Удаление', value: 'deletion' },
                            { title: 'Возражение', value: 'objection' },
                        ]"
                        density="compact"
                        variant="outlined"
                        hide-details
                        @update:model-value="loadRows"
                    />
                </v-col>
                <v-col cols="12" sm="4" class="d-flex align-center">
                    <span class="text-body-2 text-medium-emphasis">Всего: {{ total }}</span>
                </v-col>
            </v-row>
        </v-card>

        <!-- Table -->
        <v-card variant="outlined">
            <v-data-table
                :headers="headers"
                :items="filteredRows"
                :loading="loading"
                item-value="id"
                density="compact"
                no-data-text="Обращений нет"
                data-testid="pd-requests-table"
            >
                <template #[`item.received_at`]="{ item }">
                    <span class="text-caption font-mono">{{ formatDate(item.received_at) }}</span>
                </template>

                <template #[`item.contact`]="{ item }">
                    <div>
                        <span v-if="item.subject_email" class="d-block text-body-2">{{ item.subject_email }}</span>
                        <span v-if="item.subject_phone" class="d-block text-caption text-medium-emphasis">
                            {{ item.subject_phone }}
                        </span>
                        <span v-if="item.subject_full_name" class="d-block text-caption text-medium-emphasis">
                            {{ item.subject_full_name }}
                        </span>
                    </div>
                </template>

                <template #[`item.request_type`]="{ item }">
                    <v-chip
                        :color="item.request_type === 'deletion' ? 'error' : 'default'"
                        size="x-small"
                        variant="tonal"
                    >
                        {{ typeLabel(item.request_type) }}
                    </v-chip>
                </template>

                <template #[`item.status`]="{ item }">
                    <v-chip :color="statusInfo(item.status).color" size="x-small" variant="tonal">
                        {{ statusInfo(item.status).label }}
                    </v-chip>
                </template>

                <template #[`item.deadline_at`]="{ item }">
                    <span
                        class="text-caption"
                        :class="
                            item.status !== 'completed' && new Date(item.deadline_at) < new Date() ? 'text-error' : ''
                        "
                    >
                        {{ formatDate(item.deadline_at) }}
                    </span>
                </template>

                <template #[`item.actions`]="{ item }">
                    <v-btn
                        v-if="item.request_type === 'deletion' && item.status !== 'completed'"
                        color="error"
                        size="x-small"
                        variant="tonal"
                        prepend-icon="mdi-delete-forever"
                        :data-testid="`erase-btn-${item.id}`"
                        @click="openErase(item)"
                    >
                        Анонимизировать
                    </v-btn>
                    <v-chip v-else-if="item.status === 'completed'" color="success" size="x-small" variant="text">
                        Выполнено
                    </v-chip>
                </template>
            </v-data-table>
        </v-card>

        <!-- Dialog: create request -->
        <v-dialog v-model="createDialog" max-width="520" data-testid="create-dialog">
            <v-card>
                <v-card-title class="text-h6 pa-4 pb-2">Новое обращение субъекта ПДн</v-card-title>
                <v-card-text class="pa-4 pt-0">
                    <v-alert v-if="createError" type="error" variant="tonal" density="compact" class="mb-3">
                        {{ createError }}
                    </v-alert>

                    <v-select
                        v-model="createForm.request_type"
                        label="Тип обращения *"
                        :items="[
                            { title: 'Доступ к данным', value: 'access' },
                            { title: 'Исправление данных', value: 'rectification' },
                            { title: 'Удаление данных', value: 'deletion' },
                            { title: 'Возражение', value: 'objection' },
                        ]"
                        density="compact"
                        variant="outlined"
                        class="mb-3"
                        data-testid="form-request-type"
                    />

                    <v-text-field
                        v-model="createForm.subject_email"
                        label="Email субъекта"
                        type="email"
                        density="compact"
                        variant="outlined"
                        class="mb-2"
                        data-testid="form-email"
                    />
                    <v-text-field
                        v-model="createForm.subject_phone"
                        label="Телефон субъекта"
                        density="compact"
                        variant="outlined"
                        class="mb-2"
                        data-testid="form-phone"
                    />
                    <v-text-field
                        v-model="createForm.subject_full_name"
                        label="ФИО субъекта"
                        density="compact"
                        variant="outlined"
                        class="mb-2"
                    />
                    <v-text-field
                        v-model.number="createForm.tenant_id"
                        label="ID тенанта (необязательно)"
                        type="number"
                        density="compact"
                        variant="outlined"
                        class="mb-2"
                    />
                    <v-textarea
                        v-model="createForm.description"
                        label="Описание"
                        density="compact"
                        variant="outlined"
                        rows="3"
                    />
                </v-card-text>
                <v-card-actions class="pa-4 pt-0 justify-end">
                    <v-btn
                        variant="text"
                        @click="
                            createDialog = false;
                            resetCreateForm();
                        "
                        >Отмена</v-btn
                    >
                    <v-btn
                        color="primary"
                        :loading="createLoading"
                        data-testid="submit-create-btn"
                        @click="submitCreate"
                    >
                        Создать
                    </v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>

        <!-- Dialog: erase confirm -->
        <v-dialog v-model="eraseDialog" max-width="480" data-testid="erase-dialog">
            <v-card>
                <v-card-title class="text-h6 pa-4 pb-2 text-error"> Анонимизировать данные субъекта </v-card-title>
                <v-card-text class="pa-4 pt-0">
                    <template v-if="!eraseResult">
                        <v-alert type="warning" variant="tonal" density="compact" class="mb-3">
                            Операция необратима. Данные будут заменены плейсхолдерами.
                        </v-alert>
                        <p class="text-body-2 mb-1"><strong>Email:</strong> {{ eraseTarget?.subject_email ?? '—' }}</p>
                        <p class="text-body-2 mb-1">
                            <strong>Телефон:</strong> {{ eraseTarget?.subject_phone ?? '—' }}
                        </p>
                        <p class="text-body-2"><strong>Тенант:</strong> {{ eraseTarget?.tenant_id ?? 'все' }}</p>
                    </template>
                    <template v-else>
                        <v-alert type="success" variant="tonal" density="compact" class="mb-3">
                            Анонимизация выполнена.
                        </v-alert>
                        <p class="text-body-2 mb-1">
                            Пользователей: <strong>{{ eraseResult.users }}</strong>
                        </p>
                        <p class="text-body-2 mb-1">
                            Лидов поставщика: <strong>{{ eraseResult.leads }}</strong>
                        </p>
                        <p class="text-body-2 mb-1">
                            Сделок: <strong>{{ eraseResult.deals }}</strong>
                        </p>
                        <p class="text-body-2">
                            Webhook-логов: <strong>{{ eraseResult.webhook_log }}</strong>
                        </p>
                    </template>
                </v-card-text>
                <v-card-actions class="pa-4 pt-0 justify-end">
                    <v-btn variant="text" @click="eraseDialog = false">
                        {{ eraseResult ? 'Закрыть' : 'Отмена' }}
                    </v-btn>
                    <v-btn
                        v-if="!eraseResult"
                        color="error"
                        :loading="eraseLoading"
                        data-testid="confirm-erase-btn"
                        @click="confirmErase"
                    >
                        Подтвердить удаление
                    </v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>

        <v-snackbar v-model="errToastOpen" :timeout="4000" color="error" location="bottom right">
            {{ errToastText }}
        </v-snackbar>
    </v-container>
</template>

<style scoped>
.admin-pd {
    max-width: 1200px;
}
.page-title {
    font-variation-settings: 'opsz' 28;
    letter-spacing: -0.018em;
}
.font-mono {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
}
</style>
