import type { ApiReportJob, ApiReportStatus } from '../api/reports';
import type { ReportFormat, ReportJob, ReportStatus, ReportType } from './mockReports';

/**
 * API → UI converter для ReportsView.
 *
 * Schema-канон → UI mock format:
 *   pending    → queued
 *   processing → running
 *   done       → done
 *   failed     → failed
 *
 * Title строится на frontend'е (бэк не хранит) из type + period.
 * timeText зависит от status: «в очереди» / «в работе» / «time1 → time2» / «N дней назад».
 */

const STATUS_MAP: Record<ApiReportStatus, ReportStatus> = {
    pending: 'queued',
    processing: 'running',
    done: 'done',
    failed: 'failed',
};

const TYPE_TITLES: Record<ApiReportJob['type'], string> = {
    deals_export: 'Сделки · детально',
    managers_summary: 'Менеджеры',
    sources_summary: 'Источники',
    billing_summary: 'Биллинг',
};

export function mapApiReportJob(api: ApiReportJob, now: Date = new Date()): ReportJob {
    const baseTitle = TYPE_TITLES[api.type] ?? api.type;
    const title = `${baseTitle} · ${formatPeriod(api.parameters.date_from, api.parameters.date_to)}`;

    return {
        id: api.id,
        title,
        format: api.parameters.format as ReportFormat,
        status: STATUS_MAP[api.status],
        sizeText: api.file_size !== null ? formatBytes(api.file_size) : null,
        rowsText: null,
        timeText: buildTimeText(api, now),
        progress: api.status === 'processing' ? 50 : null,
        attempt: api.retry_count + 1,
        error: api.error_message,
        downloadUrl: api.download_url,
    };
}

function formatPeriod(dateFrom: string, dateTo: string): string {
    const months = ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
    const parse = (s: string): { month: string; year: number } | null => {
        const parts = s.split('-');
        if (parts.length < 3) return null;
        const yr = parseInt(parts[0]!, 10);
        const mo = parseInt(parts[1]!, 10);
        if (Number.isNaN(yr) || Number.isNaN(mo) || mo < 1 || mo > 12) return null;
        return { month: months[mo - 1]!, year: yr };
    };
    const from = parse(dateFrom);
    const to = parse(dateTo);
    if (!from || !to) return `${dateFrom} — ${dateTo}`;
    if (from.year === to.year && from.month === to.month) {
        return `${from.month} ${from.year}`;
    }
    return `${from.month} ${from.year} — ${to.month} ${to.year}`;
}

function buildTimeText(api: ApiReportJob, now: Date): string {
    if (api.status === 'pending') return 'в очереди';
    if (api.status === 'processing') {
        const sec = api.created_at
            ? Math.max(1, Math.floor((now.getTime() - new Date(api.created_at).getTime()) / 1000))
            : 0;
        return `в работе · ${sec}с`;
    }
    // done | failed
    if (api.finished_at !== null) {
        const minutesAgo = Math.floor((now.getTime() - new Date(api.finished_at).getTime()) / 60_000);
        if (minutesAgo < 1) return 'только что';
        if (minutesAgo < 60) return `${minutesAgo} мин назад`;
        if (minutesAgo < 60 * 24) return `${Math.floor(minutesAgo / 60)} ч назад`;
        return `${Math.floor(minutesAgo / (60 * 24))} д назад`;
    }
    return '';
}

function formatBytes(bytes: number): string {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

/**
 * UI ReportType slug ('deals') → API ApiReportType ('deals_export').
 */
export function uiTypeToApi(uiType: ReportType): ApiReportJob['type'] {
    const map: Record<ReportType, ApiReportJob['type']> = {
        deals: 'deals_export',
        managers: 'managers_summary',
        sources: 'sources_summary',
        billing: 'billing_summary',
    };
    return map[uiType];
}
