<script setup lang="ts">
/**
 * Таблица сделок (Sprint 3 Phase C — extraction из DealsView).
 *
 * Логически замкнутый блок: v-data-table со всеми типизированными слотами
 * (Vuetify 3.12 VDataTableSlots, Sprint 2 Phase B / O-stack-05).
 *
 * Контракт:
 *   props:
 *     - deals: MockDeal[] — отфильтрованный список (computed в родителе).
 *     - selectedIds: number[] — v-model:selected (двунаправленно).
 *     - statusBySlug: Map<string, LeadStatus> — для status-chip color/label.
 *   emits:
 *     - update:selectedIds — sync v-model selected с родителем.
 *     - row-click(deal) — раскрыть drawer.
 */
import type { MockDeal } from '../../composables/mockDeals';
import type { LeadStatus } from '../../composables/leadStatuses';
import StatusPill from '../ui/StatusPill.vue';

withDefaults(
    defineProps<{
        deals: MockDeal[];
        selectedIds: number[];
        statusBySlug: Map<string, LeadStatus>;
        // Task 15: row height from density toggle (44 comfortable / 36 compact).
        rowHeight?: number;
    }>(),
    { rowHeight: 44 },
);

const emit = defineEmits<{
    'update:selectedIds': [value: number[]];
    'row-click': [deal: MockDeal];
}>();

function onSelectedUpdate(value: number[]) {
    emit('update:selectedIds', value);
}

function formatRelative(minutes: number): string {
    if (minutes < 60) return `${minutes} мин назад`;
    if (minutes < 60 * 24) return `${Math.floor(minutes / 60)} ч назад`;
    return `${Math.floor(minutes / (60 * 24))} д назад`;
}

function formatCost(cost: number): string {
    return new Intl.NumberFormat('ru-RU').format(cost) + ' ₽';
}
</script>

<template>
    <v-card variant="outlined" class="deals-table-card">
        <v-data-table
            :model-value="selectedIds"
            :items="deals"
            :headers="[
                { title: 'Лид', key: 'name', sortable: true },
                { title: 'Статус', key: 'statusSlug', sortable: false },
                { title: 'Проект', key: 'project', sortable: false },
                { title: 'Менеджер', key: 'manager', sortable: false },
                { title: 'Стоимость', key: 'cost', align: 'end', sortable: true },
                { title: 'Время', key: 'receivedMinutesAgo', align: 'end', sortable: true },
            ]"
            show-select
            item-value="id"
            items-per-page="-1"
            hide-default-footer
            hover
            :density="rowHeight && rowHeight < 40 ? 'compact' : 'comfortable'"
            :row-props="() => ({ class: 'ld-hover-lift ld-stagger-row', style: { height: rowHeight + 'px' } })"
            @update:model-value="onSelectedUpdate"
            @click:row="(_e: Event, { item }: { item: MockDeal }) => emit('row-click', item)"
        >
            <!--
                Vuetify 3.12 типизированные слоты VDataTable (Sprint 2 Phase B / O-stack-05).
                `:items="deals"` (MockDeal[]) → Vuetify через VDataTableSlots<ItemType<T>>
                выводит `item` как `MockDeal` автоматически. Дополнительная inline-аннотация
                `{ item }: { item: MockDeal }` фиксирует этот контракт явно — IDE и vue-tsc
                проверяют доступ к полям статически.
            -->
            <template #[`item.name`]="{ item }: { item: MockDeal }">
                <div class="cell-deal">
                    <v-avatar size="32" color="primary" class="mr-3">
                        <span class="text-caption font-weight-medium">{{
                            item.name
                                .split(' ')
                                .map((p: string) => p[0])
                                .join('')
                                .slice(0, 2)
                        }}</span>
                    </v-avatar>
                    <div>
                        <div class="deal-name">{{ item.name }}</div>
                        <div class="deal-phone text-caption text-medium-emphasis ld-mono-s">{{ item.phone }}</div>
                    </div>
                </div>
            </template>

            <template #[`item.statusSlug`]="{ item }: { item: MockDeal }">
                <!-- Task 15: StatusPill заменяет v-chip + ручной dot. Label fallback на slug
                     если nameRu отсутствует (leadStatuses store ещё не загружен). -->
                <StatusPill
                    :slug="item.statusSlug"
                    :label="statusBySlug.get(item.statusSlug)?.nameRu ?? item.statusSlug"
                />
            </template>

            <template #[`item.manager`]="{ item }: { item: MockDeal }">
                <div class="cell-manager">
                    <v-avatar size="22" color="secondary" class="mr-2">
                        <span class="text-caption">{{ item.manager.initials }}</span>
                    </v-avatar>
                    {{ item.manager.name }}
                </div>
            </template>

            <template #[`item.cost`]="{ item }: { item: MockDeal }">
                <span class="num ld-mono">{{ formatCost(item.cost) }}</span>
            </template>

            <template #[`item.receivedMinutesAgo`]="{ item }: { item: MockDeal }">
                <span class="num ld-mono-s text-medium-emphasis">{{ formatRelative(item.receivedMinutesAgo) }}</span>
            </template>

            <template #[`header.data-table-select`]="{ allSelected, selectAll, someSelected }">
                <v-checkbox-btn
                    :model-value="allSelected"
                    :indeterminate="someSelected && !allSelected"
                    aria-label="Выбрать все сделки"
                    @update:model-value="selectAll"
                />
            </template>

            <template #[`item.data-table-select`]="{ isSelected, toggleSelect, internalItem, item }">
                <v-checkbox-btn
                    :model-value="isSelected(internalItem)"
                    :aria-label="`Выбрать сделку «${(item as MockDeal).name}»`"
                    @update:model-value="(v: boolean | null) => toggleSelect(internalItem)"
                />
            </template>
        </v-data-table>

        <div v-if="deals.length === 0" class="empty-state pa-8 text-center text-medium-emphasis">
            Нет сделок по выбранным фильтрам
        </div>
    </v-card>
</template>

<style scoped>
.deals-table-card {
    background: #fff;
}

.num {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-feature-settings: 'tnum';
    font-weight: 500;
}

.cell-deal {
    display: flex;
    align-items: center;
    padding: 6px 0;
}

.deal-name {
    font-weight: 500;
    color: #081319;
}

.cell-manager {
    display: flex;
    align-items: center;
}

.status-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    margin-right: 6px;
}
</style>
