<script setup lang="ts">
/**
 * Правая панель с деталями сделки. Открывается при click на строку в DealsView
 * или на карточку в KanbanView.
 *
 * Источник дизайна: liderra_v8_handoff/concepts/v8_deal_card.html.
 * MVP: hero (имя + телефон + статус-chip + close), параметры (Проект/Стоимость/
 * Источник/Email), Activity timeline (5-7 событий).
 *
 * Не входит в этот коммит:
 * - Редактирование параметров (input-fields + save).
 * - Смена статуса через dropdown (на Канбане — через DnD).
 * - Tag management, manager assignment, reminders, comment/templates —
 *   отдельные секции, отдельные коммиты.
 *
 * Backend:
 * - GET /api/deals/{id} — full detail with events.
 * - PATCH /api/deals/{id} — частичное обновление полей.
 * - GET /api/deals/{id}/events — `activity_log` фильтр по deal_id.
 */
import { computed, defineAsyncComponent, ref, watch } from 'vue';
import type { MockDeal } from '../../composables/mockDeals';
import { type DealEvent, MOCK_EVENTS } from '../../composables/mockDealEvents';
import { mapApiDealEvent } from '../../composables/dealsApiMapper';
import * as dealsApi from '../../api/deals';
import * as remindersApi from '../../api/reminders';
import type { ApiReminder } from '../../api/reminders';
import { useLeadStatusesStore } from '../../stores/leadStatuses';
import DealDetailHero from './DealDetailHero.vue';
import DealDetailTimeline from './DealDetailTimeline.vue';
// Sprint 2 Phase B / O-perf-06: ReminderDialog гейтится через v-model — chunk-split.
const ReminderDialog = defineAsyncComponent(() => import('../reminders/ReminderDialog.vue'));

const leadStatusesStore = useLeadStatusesStore();

const props = defineProps<{
    open: boolean;
    deal: MockDeal | null;
    tenantId?: number;
}>();

const emit = defineEmits<{ 'update:open': [value: boolean] }>();

const drawerOpen = computed({
    get: () => props.open,
    set: (v) => emit('update:open', v),
});

const status = computed(() => {
    if (!props.deal) return null;
    return leadStatusesStore.findBySlug(props.deal.statusSlug);
});

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

// Activity timeline: при наличии tenant_id делаем GET /api/deals/{id} и
// показываем реальные events. На fail / без tenant_id — fallback на MOCK_EVENTS.
const events = ref<DealEvent[]>([...MOCK_EVENTS]);
const eventsLoading = ref(false);
const eventsFetchError = ref(false);

// Comment editor — редактирование текущего комментария сделки.
const commentDraft = ref<string>('');
const commentSaving = ref(false);
const commentSaveError = ref(false);
const commentToastOpen = ref(false);
const commentToastText = ref('');

// Reminders на сделку — отдельная секция с inline-create + список.
const reminders = ref<ApiReminder[]>([]);
const remindersLoading = ref(false);
const reminderDialogOpen = ref(false);

async function loadReminders() {
    if (!props.deal || !props.tenantId) {
        reminders.value = [];
        return;
    }
    remindersLoading.value = true;
    try {
        const res = await remindersApi.listReminders({ filter: 'active', dealId: props.deal.id });
        reminders.value = res.items;
    } catch {
        reminders.value = [];
    } finally {
        remindersLoading.value = false;
    }
}

async function completeReminderInDrawer(id: number) {
    try {
        await remindersApi.completeReminder(id);
        reminders.value = reminders.value.filter((r) => r.id !== id);
    } catch {
        /* silent */
    }
}

function onReminderSaved() {
    void loadReminders();
}

function formatReminderTime(iso: string | null): string {
    if (!iso) return '—';
    const ms = new Date(iso).getTime() - Date.now();
    const min = Math.round(Math.abs(ms) / 60_000);
    const future = ms > 0;
    if (min < 60) return future ? `через ${min} мин` : `${min} мин назад`;
    const hr = Math.round(min / 60);
    if (hr < 24) return future ? `через ${hr} ч` : `${hr} ч назад`;
    const days = Math.round(hr / 24);
    return future ? `через ${days} д` : `${days} д назад`;
}

async function loadEvents() {
    if (!props.deal || !props.tenantId) {
        events.value = [...MOCK_EVENTS];
        commentDraft.value = '';
        return;
    }
    eventsLoading.value = true;
    eventsFetchError.value = false;
    try {
        const res = await dealsApi.getDeal(props.deal.id, props.tenantId);
        events.value = res.events.map((e) => mapApiDealEvent(e));
        commentDraft.value = res.deal.comment ?? '';
    } catch {
        eventsFetchError.value = true;
        events.value = [...MOCK_EVENTS];
        commentDraft.value = '';
    } finally {
        eventsLoading.value = false;
    }
}

async function saveComment() {
    if (!props.deal || !props.tenantId) return;
    commentSaving.value = true;
    commentSaveError.value = false;
    try {
        await dealsApi.updateDeal(props.deal.id, {
            tenant_id: props.tenantId,
            comment: commentDraft.value || null,
        });
        commentToastText.value = 'Комментарий сохранён.';
        commentToastOpen.value = true;
        // Reload events чтобы показать новый deal.commented в timeline.
        await loadEvents();
    } catch {
        commentSaveError.value = true;
        commentToastText.value = 'Не удалось сохранить — попробуйте позже.';
        commentToastOpen.value = true;
    } finally {
        commentSaving.value = false;
    }
}

// Fetch при открытии drawer'а или смене сделки.
watch(
    () => [props.open, props.deal?.id, props.tenantId] as const,
    ([open]) => {
        if (open) {
            loadEvents();
            void loadReminders();
        }
    },
    { immediate: true },
);

defineExpose({
    events,
    eventsLoading,
    eventsFetchError,
    loadEvents,
    commentDraft,
    commentSaving,
    commentSaveError,
    commentToastOpen,
    commentToastText,
    saveComment,
});
</script>

<template>
    <v-navigation-drawer v-model="drawerOpen" location="right" temporary :width="480" class="deal-drawer">
        <div v-if="deal" class="drawer-content">
            <DealDetailHero :deal="deal" :status="status" @close="drawerOpen = false" />

            <v-divider />

            <section class="section pa-5">
                <h3 class="section-title text-subtitle-2 mb-3">Параметры</h3>
                <dl class="params">
                    <div class="param">
                        <dt class="text-caption text-medium-emphasis">Проект</dt>
                        <dd class="text-body-2">{{ deal.project }}</dd>
                    </div>
                    <div class="param">
                        <dt class="text-caption text-medium-emphasis">Стоимость лида</dt>
                        <dd class="text-body-2 num">{{ formatCost(deal.cost) }}</dd>
                    </div>
                    <div class="param">
                        <dt class="text-caption text-medium-emphasis">Менеджер</dt>
                        <dd class="text-body-2">
                            <v-avatar size="20" color="secondary" class="mr-1">
                                <span class="text-caption">{{ deal.manager.initials }}</span>
                            </v-avatar>
                            {{ deal.manager.name }}
                        </dd>
                    </div>
                    <div class="param">
                        <dt class="text-caption text-medium-emphasis">Источник</dt>
                        <dd class="text-body-2 link">Я.Директ → landing-1</dd>
                    </div>
                </dl>
            </section>

            <v-divider />

            <section v-if="tenantId" class="section pa-5" data-testid="comment-section">
                <h3 class="section-title text-subtitle-2 mb-3">Комментарий</h3>
                <v-textarea
                    v-model="commentDraft"
                    placeholder="Заметка менеджера…"
                    variant="outlined"
                    density="comfortable"
                    auto-grow
                    rows="3"
                    hide-details
                    counter="5000"
                    data-testid="comment-textarea"
                />
                <div class="d-flex ga-2 mt-2 justify-end">
                    <v-btn
                        :loading="commentSaving"
                        color="primary"
                        size="small"
                        prepend-icon="mdi-content-save-outline"
                        data-testid="save-comment-btn"
                        @click="saveComment"
                    >
                        Сохранить
                    </v-btn>
                </div>
            </section>

            <v-divider v-if="tenantId" />

            <section v-if="tenantId && deal" class="section pa-5" data-testid="reminders-section">
                <div class="d-flex justify-space-between align-center mb-3">
                    <h3 class="section-title text-subtitle-2 mb-0">Напоминания</h3>
                    <v-btn
                        size="x-small"
                        variant="text"
                        prepend-icon="mdi-plus"
                        data-testid="add-reminder-btn"
                        @click="reminderDialogOpen = true"
                    >
                        Создать
                    </v-btn>
                </div>
                <div v-if="reminders.length === 0 && !remindersLoading" class="text-caption text-medium-emphasis">
                    Нет активных напоминаний.
                </div>
                <ul v-else class="reminders-list">
                    <li v-for="r in reminders" :key="r.id" class="reminder-row" data-testid="drawer-reminder-item">
                        <v-btn
                            icon="mdi-check-circle-outline"
                            size="x-small"
                            variant="text"
                            density="comfortable"
                            :data-testid="`drawer-complete-${r.id}`"
                            @click="completeReminderInDrawer(r.id)"
                        />
                        <div class="reminder-body">
                            <div class="reminder-text">{{ r.text || 'Без описания' }}</div>
                            <div class="reminder-meta text-caption text-medium-emphasis">
                                {{ formatReminderTime(r.remind_at) }}
                            </div>
                        </div>
                    </li>
                </ul>
            </section>

            <v-divider v-if="tenantId && deal" />

            <DealDetailTimeline :events="events" :events-fetch-error="eventsFetchError" />

            <v-snackbar
                v-model="commentToastOpen"
                :timeout="3000"
                :color="commentSaveError ? 'warning' : undefined"
                data-testid="comment-toast"
                location="bottom right"
            >
                {{ commentToastText }}
            </v-snackbar>

            <ReminderDialog
                v-if="tenantId && deal"
                v-model="reminderDialogOpen"
                :deal-id="deal.id"
                @saved="onReminderSaved"
            />
        </div>
    </v-navigation-drawer>
</template>

<style scoped>
.deal-drawer {
    background: #fff;
}

.drawer-content {
    display: flex;
    flex-direction: column;
}

.section-title {
    font-weight: 600;
    color: #081319;
}

.params {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px 12px;
    margin: 0;
}
.param dt {
    font-size: 11px;
    margin-bottom: 2px;
}
.param dd {
    margin: 0;
    color: #081319;
}
.param .link {
    color: #0f6e56;
    cursor: pointer;
}
.param .link:hover {
    text-decoration: underline;
}

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

.reminders-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.reminder-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border: 1px solid #e8e3d6;
    border-radius: 6px;
    background: #fdfaf3;
}

.reminder-body {
    flex: 1;
    min-width: 0;
}

.reminder-text {
    font-size: 13px;
    line-height: 1.4;
    color: #081319;
}

.reminder-meta {
    margin-top: 2px;
}
</style>
