<?php

namespace App\Jobs;

use App\Models\AiAction;
use App\Models\Issue;
use App\Models\Server;
use App\Models\Ticket;
use App\Notify\Dispatcher;
use App\Notify\Message;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;

/**
 * Once-daily summary, fired through every notification channel that has
 * subscribed to `daily_digest`. Default schedule: 08:00 BDT.
 *
 * Lightweight — just counts. Designed to be the operator's first morning
 * read: "what happened overnight, what needs attention today".
 */
class SendDailyDigest implements ShouldQueue, ShouldBeUnique
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $uniqueFor = 3600;
    public int $tries = 1;

    public function uniqueId(): string { return 'daily-digest-' . now('Asia/Dhaka')->format('Y-m-d'); }

    public function handle(Dispatcher $notifier): void
    {
        $auditConn = config('database.audit_connection', 'mysql_audit');
        $since24h = now()->subHours(24);

        $stats = [
            'audits_run'     => DB::connection($auditConn)->table('audit_logs')
                                ->where('action', 'audit.completed')
                                ->where('logged_at', '>=', $since24h)->count(),
            'audits_failed'  => DB::connection($auditConn)->table('audit_logs')
                                ->where('action', 'audit.failed')
                                ->where('logged_at', '>=', $since24h)->count(),
            'actions_completed' => AiAction::where('status', 'completed')
                                ->where('completed_at', '>=', $since24h)->count(),
            'actions_failed' => AiAction::where('status', 'failed')
                                ->where('completed_at', '>=', $since24h)->count(),
            'pending_now'    => AiAction::where('status', 'pending')->count(),
            'issues_opened'  => Issue::where('detected_at', '>=', $since24h)->count(),
            'issues_fixed'   => Issue::where('resolved_at',  '>=', $since24h)->count(),
            'critical_open'  => Issue::where('status', 'open')->where('severity', 'critical')->count(),
            'high_open'      => Issue::where('status', 'open')->where('severity', 'high')->count(),
            'tickets_open'   => Ticket::whereIn('status', ['open', 'ai_drafted'])->count(),
            'anomalies_24h'  => DB::connection($auditConn)->table('anomaly_events')
                                ->where('detected_at', '>=', $since24h)->count(),
            'ai_spend_24h'   => DB::table('ai_costs')->where('called_at', '>=', $since24h)->sum('cost_usd'),
        ];

        $servers = Server::select('status', DB::raw('count(*) as n'))->groupBy('status')->pluck('n', 'status');

        $criticalServers = Server::where('status', 'critical')->pluck('hostname')->all();

        $body  = "═══ Last 24 hours ═══\n\n";
        $body .= "Audits:           {$stats['audits_run']} run, {$stats['audits_failed']} failed\n";
        $body .= "AI actions:       {$stats['actions_completed']} completed, {$stats['actions_failed']} failed, {$stats['pending_now']} pending\n";
        $body .= "Issues:           {$stats['issues_opened']} opened, {$stats['issues_fixed']} fixed\n";
        $body .= "Open severity:    {$stats['critical_open']} critical, {$stats['high_open']} high\n";
        $body .= "Tickets:          {$stats['tickets_open']} open\n";
        $body .= "Security:         {$stats['anomalies_24h']} anomalies detected\n";
        $body .= "AI spend:         $" . number_format($stats['ai_spend_24h'], 2) . "\n\n";

        $body .= "═══ Server fleet ═══\n";
        foreach ($servers as $status => $n) {
            $body .= str_pad("  " . $status, 18) . $n . "\n";
        }

        if ($criticalServers) {
            $body .= "\n⚠ Servers in CRITICAL state:\n";
            foreach ($criticalServers as $h) $body .= "  · {$h}\n";
        }

        $worstSeverity = $stats['critical_open'] > 0 ? 'critical'
                      : ($stats['high_open']     > 0 ? 'high' : 'info');

        $notifier->dispatch(new Message(
            event:    'daily_digest',
            title:    'Daily digest — ' . now('Asia/Dhaka')->format('D, M j'),
            body:     trim($body),
            severity: $worstSeverity,
            url:      rtrim((string) config('app.url'), '/') . '/dashboard',
            context:  $stats,
        ));
    }
}
