<?php

declare(strict_types=1);

namespace App\Services\Reports\Providers;

use App\Models\ReportJob;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

/**
 * billing_summary — агрегат balance_transactions по типу операции (audit F1).
 *
 * Группировка по balance_transactions.type; count + SUM(amount_rub). Тип
 * операции переводится в человекочитаемую метку. parameters: date_from,
 * date_to (Y-m-d) — фильтр по created_at.
 *
 * RLS-обёртка SET LOCAL app.current_tenant_id (balance_transactions имеет RLS
 * tenant_isolation) + явный where('tenant_id') — паттерн BillingController.
 */
class BillingSummaryProvider implements ReportDataProvider
{
    /** Канон-типы balance_transactions.type → RU-метка (schema §7.6 CHECK). */
    private const TYPE_LABELS = [
        'trial_bonus' => 'Стартовый бонус',
        'topup' => 'Пополнение',
        'lead_charge' => 'Списание за лиды',
        'refund' => 'Возврат',
        'manual_adjustment' => 'Ручная корректировка',
        'historical_import' => 'Импорт истории',
        'chargeback_writedown' => 'Chargeback — списание в долг',
        'chargeback_repayment' => 'Chargeback — погашение долга',
    ];

    public function headers(): array
    {
        return ['Тип операции', 'Количество', 'Сумма (₽)'];
    }

    public function rows(ReportJob $job): array
    {
        $params = $job->parameters ?? [];
        $dateFrom = Carbon::parse($params['date_from'])->startOfDay();
        $dateTo = Carbon::parse($params['date_to'])->endOfDay();

        return DB::transaction(function () use ($job, $dateFrom, $dateTo): array {
            DB::statement('SET LOCAL app.current_tenant_id = '.(int) $job->tenant_id);

            $rows = DB::table('balance_transactions')
                ->where('tenant_id', $job->tenant_id)
                ->whereBetween('created_at', [$dateFrom, $dateTo])
                ->groupBy('type')
                ->orderBy('type')
                ->selectRaw('type, COUNT(*) AS cnt, COALESCE(SUM(amount_rub), 0) AS sum_rub')
                ->get();

            return $rows->map(function ($row): array {
                $label = self::TYPE_LABELS[$row->type] ?? (string) $row->type;

                return [$label, (int) $row->cnt, (string) $row->sum_rub];
            })->all();
        });
    }

    public function slug(): string
    {
        return 'billing';
    }
}
