<script setup lang="ts">
/**
 * Список «Сгенерированные отчёты» (Sprint 3 Phase C — extraction из ReportsView).
 *
 * Логически замкнутый блок: header + ul-список заданий со статусами,
 * progress-bar для running, action-кнопки (download/retry/cancel/delete)
 * по состоянию.
 *
 * Все side-effect handler'ы (onRetry/onCancel/askDelete) — в родителе через emit.
 */
import type { ReportJob, ReportStatus } from '../../composables/mockReports';

defineProps<{
    jobs: ReportJob[];
}>();

defineEmits<{
    retry: [jobId: number];
    cancel: [jobId: number];
    'request-delete': [jobId: number];
}>();

function statusColor(status: ReportStatus): string {
    if (status === 'done') return 'success';
    if (status === 'running') return 'primary';
    if (status === 'queued') return 'info';
    return 'error';
}

function statusLabel(job: ReportJob): string {
    if (job.status === 'done') return 'Готов';
    if (job.status === 'running') return `В работе`;
    if (job.status === 'queued') return 'В очереди';
    return 'Ошибка';
}

function statusIcon(status: ReportStatus): string {
    if (status === 'done') return 'mdi-check-circle';
    if (status === 'running') return 'mdi-progress-clock';
    if (status === 'queued') return 'mdi-clock-outline';
    return 'mdi-alert-circle-outline';
}

function jobMeta(job: ReportJob): string {
    const parts: string[] = [];
    parts.push(job.format.toUpperCase());
    if (job.sizeText) parts.push(job.sizeText);
    if (job.rowsText) parts.push(job.rowsText);
    if (job.status === 'failed' && job.error) {
        parts.push(`${job.attempt}/3 попытки`);
        parts.push(`ошибка: ${job.error}`);
    }
    parts.push(job.timeText);
    return parts.filter((p) => p.length > 0).join(' · ');
}

function canRetry(job: ReportJob): boolean {
    return job.status === 'failed' && job.attempt < 3;
}
</script>

<template>
    <v-card variant="outlined" class="mt-4 panel">
        <div class="panel-h pa-4">
            <div>
                <h2 class="text-h6 ma-0">Сгенерированные отчёты</h2>
                <p class="text-caption text-medium-emphasis ma-0">
                    retry-failed для owner отчёта, до 3 попыток · 7 дней
                </p>
            </div>
        </div>
        <v-divider />
        <div v-if="jobs.length === 0" class="empty-state pa-8 text-center text-medium-emphasis">
            Нет отчётов. Запросите первый — кнопка «Запустить» выше.
        </div>
        <ul v-else class="jobs-list pa-0 ma-0">
            <li v-for="job in jobs" :key="job.id" class="job-row" :data-testid="`job-${job.id}`">
                <v-icon :color="statusColor(job.status)" class="job-icon" size="22">
                    {{ statusIcon(job.status) }}
                </v-icon>
                <div class="job-info">
                    <div class="job-title">{{ job.title }}</div>
                    <div class="job-meta text-caption text-medium-emphasis">
                        {{ jobMeta(job) }}
                    </div>
                    <v-progress-linear
                        v-if="job.status === 'running' && job.progress !== null"
                        :model-value="job.progress"
                        color="primary"
                        height="3"
                        rounded
                        indeterminate
                        class="mt-1"
                    />
                </div>
                <v-chip size="small" variant="tonal" :color="statusColor(job.status)">
                    {{ statusLabel(job) }}
                </v-chip>
                <div class="job-actions">
                    <v-btn
                        v-if="job.status === 'done' && job.downloadUrl"
                        :href="job.downloadUrl"
                        icon="mdi-download"
                        variant="text"
                        size="small"
                        aria-label="Скачать"
                        :data-testid="`download-${job.id}`"
                    />
                    <v-btn
                        v-if="canRetry(job)"
                        icon="mdi-refresh"
                        variant="text"
                        size="small"
                        color="warning"
                        aria-label="Повторить"
                        :data-testid="`retry-${job.id}`"
                        @click="$emit('retry', job.id)"
                    />
                    <v-btn
                        v-if="job.status === 'queued'"
                        icon="mdi-close"
                        variant="text"
                        size="small"
                        aria-label="Отменить"
                        :data-testid="`cancel-${job.id}`"
                        @click="$emit('cancel', job.id)"
                    />
                    <v-btn
                        v-if="job.status === 'done' || job.status === 'failed'"
                        icon="mdi-delete-outline"
                        variant="text"
                        size="small"
                        aria-label="Удалить"
                        :data-testid="`delete-${job.id}`"
                        @click="$emit('request-delete', job.id)"
                    />
                </div>
            </li>
        </ul>
    </v-card>
</template>

<style scoped>
.panel {
    background: #fff;
}

.panel-h {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 12px;
}

.empty-state {
    font-size: 14px;
}

.jobs-list {
    list-style: none;
}

.job-row {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    gap: 12px;
    align-items: center;
    padding: 14px 16px;
    border-bottom: 1px solid #f0ede4;
}
.job-row:last-child {
    border-bottom: none;
}

.job-icon {
    flex-shrink: 0;
}

.job-info {
    min-width: 0;
}

.job-title {
    font-weight: 500;
    color: #081319;
    line-height: 1.3;
}

.job-meta {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-feature-settings: 'tnum';
    font-size: 11px;
    margin-top: 2px;
}

.job-actions {
    display: flex;
    gap: 4px;
}
</style>
