<?php

namespace App\Modules\Admin\Operations\Services;

use App\Modules\Exports\Models\Export;
use App\Modules\Exports\Support\ExportStatus;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

final class RetentionPolicyService
{
    /**
     * @return array{exports_deleted: int, notification_rows_deleted: int, activity_logs_deleted: int}
     */
    public function run(): array
    {
        return [
            'exports_deleted' => $this->cleanupExports(),
            'notification_rows_deleted' => $this->cleanupNotifications(),
            'activity_logs_deleted' => $this->cleanupActivityLogs(),
        ];
    }

    private function cleanupExports(): int
    {
        $keepDays = (int) config('retention.exports_keep_days', 30);
        $cutoff = now()->subDays(max(1, $keepDays));

        $rows = Export::query()
            ->withoutGlobalScopes()
            ->whereIn('status', [ExportStatus::COMPLETED, ExportStatus::FAILED])
            ->where('created_at', '<', $cutoff)
            ->whereNotNull('file_path')
            ->limit(500)
            ->get(['id', 'file_path']);

        foreach ($rows as $row) {
            Storage::disk('local')->delete((string) $row->file_path);
        }

        $ids = $rows->pluck('id')->all();
        if ($ids === []) {
            return 0;
        }

        return Export::query()
            ->withoutGlobalScopes()
            ->whereIn('id', $ids)
            ->delete();
    }

    private function cleanupNotifications(): int
    {
        $keepDays = (int) config('retention.notifications_keep_days', 90);
        $cutoff = now()->subDays(max(1, $keepDays));

        return DB::table('notifications')
            ->where('created_at', '<', $cutoff)
            ->delete();
    }

    private function cleanupActivityLogs(): int
    {
        $keepDays = (int) config('retention.activity_logs_keep_days', 365);
        $cutoff = now()->subDays(max(1, $keepDays));

        return DB::table('activity_logs')
            ->where('created_at', '<', $cutoff)
            ->delete();
    }
}

