<?php

declare(strict_types=1);

namespace App\Services\Reports\Providers;

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

/**
 * sources_summary — агрегат сделок по источнику (utm_source) за период (audit F1).
 *
 * Группировка по deals.utm_source; сделки без метки (NULL/пусто) сводятся в
 * строку «Прямые / без метки». «Оплачено» = status='won'. Конверсия =
 * won / total * 100, округление до 0.1.
 *
 * parameters: date_from, date_to (Y-m-d). Исключаются soft-deleted и тестовые
 * сделки. RLS-обёртка SET LOCAL app.current_tenant_id — паттерн DealsExportProvider.
 */
class SourcesSummaryProvider implements ReportDataProvider
{
    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('deals')
                ->where('tenant_id', $job->tenant_id)
                ->whereNull('deleted_at')
                ->where('is_test', false)
                ->whereBetween('received_at', [$dateFrom, $dateTo])
                ->groupBy('utm_source')
                ->orderByRaw('COUNT(*) DESC')
                ->orderBy('utm_source')
                ->selectRaw(
                    "utm_source,
                     COUNT(*) AS total,
                     COUNT(*) FILTER (WHERE status = 'won') AS paid"
                )
                ->get();

            return $rows->map(function ($row): array {
                $source = $row->utm_source !== null && trim((string) $row->utm_source) !== ''
                    ? (string) $row->utm_source
                    : 'Прямые / без метки';
                $total = (int) $row->total;
                $paid = (int) $row->paid;
                $conversion = $total > 0 ? round($paid / $total * 100, 1) : 0.0;

                return [$source, $total, $paid, $conversion];
            })->all();
        });
    }

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