<?php

namespace App\Jobs;

use App\Models\BackupSchedule;
use App\Models\BackupScheduleRun;
use App\Models\BackupSet;
use App\Services\Intune\AuditLogger;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Collection;

class ApplyBackupScheduleRetentionJob implements ShouldQueue
{
    use Queueable;

    public function __construct(public int $backupScheduleId) {}

    public function handle(AuditLogger $auditLogger): void
    {
        $schedule = BackupSchedule::query()
            ->with('tenant')
            ->find($this->backupScheduleId);

        if (! $schedule || ! $schedule->tenant) {
            return;
        }

        $keepLast = (int) ($schedule->retention_keep_last ?? 30);

        if ($keepLast < 1) {
            $keepLast = 1;
        }

        /** @var Collection<int, int> $keepBackupSetIds */
        $keepBackupSetIds = BackupScheduleRun::query()
            ->where('backup_schedule_id', $schedule->id)
            ->whereNotNull('backup_set_id')
            ->orderByDesc('scheduled_for')
            ->limit($keepLast)
            ->pluck('backup_set_id')
            ->filter()
            ->values();

        /** @var Collection<int, int> $deleteBackupSetIds */
        $deleteBackupSetIds = BackupScheduleRun::query()
            ->where('backup_schedule_id', $schedule->id)
            ->whereNotNull('backup_set_id')
            ->when($keepBackupSetIds->isNotEmpty(), fn ($query) => $query->whereNotIn('backup_set_id', $keepBackupSetIds->all()))
            ->pluck('backup_set_id')
            ->filter()
            ->unique()
            ->values();

        if ($deleteBackupSetIds->isEmpty()) {
            $auditLogger->log(
                tenant: $schedule->tenant,
                action: 'backup_schedule.retention_applied',
                resourceType: 'backup_schedule',
                resourceId: (string) $schedule->id,
                status: 'success',
                context: [
                    'metadata' => [
                        'keep_last' => $keepLast,
                        'deleted_backup_sets' => 0,
                    ],
                ],
            );

            return;
        }

        $deletedCount = 0;

        BackupSet::query()
            ->where('tenant_id', $schedule->tenant_id)
            ->whereIn('id', $deleteBackupSetIds->all())
            ->whereNull('deleted_at')
            ->chunkById(200, function (Collection $sets) use (&$deletedCount): void {
                foreach ($sets as $set) {
                    $set->delete();
                    $deletedCount++;
                }
            });

        $auditLogger->log(
            tenant: $schedule->tenant,
            action: 'backup_schedule.retention_applied',
            resourceType: 'backup_schedule',
            resourceId: (string) $schedule->id,
            status: 'success',
            context: [
                'metadata' => [
                    'keep_last' => $keepLast,
                    'deleted_backup_sets' => $deletedCount,
                ],
            ],
        );
    }
}
