<?php

declare(strict_types=1);

namespace App\Services\Reports\Providers;

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

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

            return $rows->map(function ($row): array {
                $name = trim(($row->first_name ?? '').' '.($row->last_name ?? ''));
                if ($name === '') {
                    $name = (string) ($row->email ?? '');
                }
                if ($name === '') {
                    $name = 'Не назначен';
                }
                $total = (int) $row->total;
                $paid = (int) $row->paid;
                $conversion = $total > 0 ? round($paid / $total * 100, 1) : 0.0;

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

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