<?php

namespace App\Jobs;

use App\Mail\AdminAnalyticsReportMail;
use App\Models\Transaction;
use App\Services\SystemSettingService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Mail;

class SendAdminAnalyticsReportJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public string $frequency = 'daily')
    {
        $this->onQueue('default');
    }

    public function handle(SystemSettingService $systemSettingService): void
    {
        $section = 'admin.reports';
        $enabled = (bool) $systemSettingService->get(
            $section,
            $this->frequency === 'weekly' ? 'weekly_enabled' : 'daily_enabled',
            false
        );

        if (! $enabled) {
            return;
        }

        $rawRecipients = (string) $systemSettingService->get($section, 'recipients_csv', '');
        $recipients = collect(explode(',', $rawRecipients))
            ->map(fn (string $email) => strtolower(trim($email)))
            ->filter(fn (string $email) => filter_var($email, FILTER_VALIDATE_EMAIL))
            ->unique()
            ->values();

        if ($recipients->isEmpty()) {
            return;
        }

        $end = now();
        $start = $this->frequency === 'weekly'
            ? now()->subDays(6)->startOfDay()
            : now()->startOfDay();

        $rows = Transaction::query()
            ->selectRaw('DATE(created_at) as day, COUNT(*) as total, COALESCE(SUM(amount_charged),0) as gross, COALESCE(SUM(profit),0) as profit')
            ->whereBetween('created_at', [$start, $end])
            ->groupBy('day')
            ->orderBy('day')
            ->get();

        $statusCounts = Transaction::query()
            ->selectRaw('status, COUNT(*) as total')
            ->whereBetween('created_at', [$start, $end])
            ->groupBy('status')
            ->pluck('total', 'status');

        $totals = [
            'transactions' => (int) ($rows->sum('total') ?? 0),
            'gross' => round((float) ($rows->sum('gross') ?? 0), 2),
            'profit' => round((float) ($rows->sum('profit') ?? 0), 2),
            'success' => (int) ($statusCounts['success'] ?? 0),
            'pending' => (int) ($statusCounts['pending'] ?? 0),
            'failed' => (int) (($statusCounts['failed'] ?? 0) + ($statusCounts['reversed'] ?? 0)),
            'stuck' => (int) ($statusCounts['stuck'] ?? 0),
        ];

        Mail::to($recipients->all())
            ->queue(new AdminAnalyticsReportMail(
                frequency: $this->frequency,
                start: Carbon::parse($start),
                end: Carbon::parse($end),
                rows: $rows->toArray(),
                totals: $totals,
            ));
    }
}
