<template>
    <div class="charges-tab">
        <div class="d-flex align-center mb-4 ga-3 flex-wrap">
            <v-select
                v-model="period"
                :items="periods"
                item-title="title"
                item-value="value"
                label="Период"
                density="compact"
                hide-details
                style="max-width: 220px"
                @update:model-value="refresh"
            />
            <v-spacer />
            <v-btn color="primary" prepend-icon="mdi-download" :loading="exporting" @click="exportCsv">
                Скачать CSV
            </v-btn>
        </div>

        <v-data-table-server
            :headers="headers"
            :items="rows"
            :items-length="total"
            :loading="loading"
            :items-per-page="20"
            class="numeric-tnum"
            @update:options="loadOptions"
        >
            <template #[`item.charged_at`]="{ item }">
                {{ formatDate(item.charged_at) }}
            </template>
            <template #[`item.deal_id`]="{ item }">
                <RouterLink :to="`/deals/${item.deal_id}`">#{{ item.deal_id }}</RouterLink>
            </template>
            <template #[`item.price_rub`]="{ item }">
                <span v-if="item.price_per_lead_kopecks === 0" class="text-medium-emphasis">
                    0 ₽
                    <v-tooltip
                        activator="parent"
                        text="До перехода на новую модель эти лиды списывались из бесплатного остатка."
                    />
                    <span class="text-caption ml-1">(из бесплатного)</span>
                </span>
                <span v-else>{{ formatRub(item.price_per_lead_kopecks) }}&nbsp;₽</span>
            </template>
        </v-data-table-server>
    </div>
</template>

<script setup lang="ts">
/**
 * ChargesTab — read-only ledger списаний за лиды (Plan 4 Task 11).
 *
 * Backend: GET /api/billing/charges?page=N&period=...
 *          POST /api/billing/charges/export → CSV blob.
 *
 * Pagination server-side через v-data-table-server (20/page).
 * Фильтры: period (current_month / last_month / 90d).
 * Исторические prepaid-строки (price_per_lead_kopecks=0) помечены
 * тултипом «До перехода на новую модель...».
 * RLS: tenant-isolation на backend, frontend просто читает то что вернули.
 *
 * defineExpose ниже — для Vitest unit-тестов (`refresh`/`exportCsv`/`period`/
 * `total`/`load`).
 */
import { ref, onMounted } from 'vue';
import axios from 'axios';

interface ChargeRow {
    id: number;
    charged_at: string;
    deal_id: number;
    tier_no: number;
    charge_source: 'prepaid' | 'rub';
    price_per_lead_kopecks: number;
}

// Формат денег ru-RU (запятая-десятичный + разделитель тысяч) — единообразно
// с биллингом (раньше было «12.50» через toFixed, без разделителя).
const rubFmt = new Intl.NumberFormat('ru-RU', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
function formatRub(kopecks: number): string {
    return rubFmt.format(kopecks / 100);
}

const rows = ref<ChargeRow[]>([]);
const total = ref(0);
const loading = ref(false);
const exporting = ref(false);
const period = ref<string>('current_month');
const page = ref(1);

const periods = [
    { title: 'Текущий месяц', value: 'current_month' },
    { title: 'Прошлый месяц', value: 'last_month' },
    { title: 'Последние 90 дней', value: '90d' },
];

const headers = [
    { title: 'Дата', key: 'charged_at', sortable: false },
    { title: 'Сделка', key: 'deal_id', sortable: false, width: 100 },
    { title: 'Tier', key: 'tier_no', sortable: false, width: 80 },
    { title: 'Цена', key: 'price_rub', sortable: false, width: 160 },
];

function formatDate(iso: string): string {
    return new Date(iso).toLocaleString('ru-RU', { timeZone: 'Europe/Moscow' });
}

async function refresh(): Promise<void> {
    page.value = 1;
    await load();
}

async function loadOptions(opts: { page: number }): Promise<void> {
    page.value = opts.page;
    await load();
}

async function load(): Promise<void> {
    loading.value = true;
    try {
        const params: Record<string, string | number> = { page: page.value, period: period.value };
        const { data } = await axios.get('/api/billing/charges', { params });
        rows.value = data.data;
        total.value = data.meta.total;
    } finally {
        loading.value = false;
    }
}

async function exportCsv(): Promise<void> {
    exporting.value = true;
    try {
        const params: Record<string, string> = { period: period.value };
        const response = await axios.post('/api/billing/charges/export', params, { responseType: 'blob' });
        // jsdom не реализует URL.createObjectURL — gracefully no-op (тесты мокают).
        if (typeof URL.createObjectURL !== 'function') return;
        const url = URL.createObjectURL(response.data);
        const a = document.createElement('a');
        a.href = url;
        a.download = `charges_${new Date().toISOString().slice(0, 10)}.csv`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    } finally {
        exporting.value = false;
    }
}

onMounted(load);

defineExpose({ refresh, exportCsv, load, period, total });
</script>

<style scoped>
.charges-tab {
    padding-top: 8px;
}
.numeric-tnum :deep(td) {
    font-feature-settings: 'tnum';
    font-family: 'JetBrains Mono', ui-monospace, monospace;
}
</style>
