<?php

namespace Modules\Lpj\Jobs;

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\Facades\DB;
use Illuminate\Support\Facades\Log;
use Modules\Lpj\Models\Inspeksi;

/**
 * Job untuk membersihkan data inspeksi yang tidak memiliki dokument_id
 * 
 * Case: Jika ada data inspeksi yang masuk dengan permohonan_id yang sama
 * tetapi memiliki dokument_id dan user created_by yang sama, maka
 * data lama (tanpa dokument_id) akan di-soft delete
 */
class CleanupInspeksiDataJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $timeout = 300; // 5 menit
    public $tries = 3;
    public $maxExceptions = 3;
    public $backoff = [60, 120, 300]; // Exponential backoff dalam detik

    protected int $permohonanId;
    protected int $createdBy;
    protected ?int $dokumentId;

    /**
     * Create a new job instance.
     *
     * @param int $permohonanId
     * @param int $createdBy
     * @param int|null $dokumentId
     */
    public function __construct(int $permohonanId, int $createdBy, ?int $dokumentId = null)
    {
        $this->permohonanId = $permohonanId;
        $this->createdBy = $createdBy;
        $this->dokumentId = $dokumentId;
    }

    /**
     * Execute the job.
     *
     * @return void
     * @throws \Exception
     */
    public function handle(): void
    {
        Log::info('CleanupInspeksiDataJob: Memulai proses cleanup data inspeksi', [
            'permohonan_id' => $this->permohonanId,
            'created_by' => $this->createdBy,
            'dokument_id' => $this->dokumentId
        ]);

        DB::beginTransaction();

        try {
            // Cari data inspeksi yang memiliki dokument_id (data baru)
            $newInspeksi = Inspeksi::where('permohonan_id', $this->permohonanId)
                ->where('created_by', $this->createdBy)
                ->whereNotNull('dokument_id')
                ->whereNull('deleted_at')
                ->first();

            if (!$newInspeksi) {
                Log::warning('CleanupInspeksiDataJob: Tidak ditemukan data inspeksi baru dengan dokument_id', [
                    'permohonan_id' => $this->permohonanId,
                    'created_by' => $this->createdBy
                ]);
                DB::rollBack();
                return;
            }

            Log::info('CleanupInspeksiDataJob: Data inspeksi baru ditemukan', [
                'inspeksi_id' => $newInspeksi->id,
                'dokument_id' => $newInspeksi->dokument_id
            ]);

            // Cari data inspeksi lama yang tidak memiliki dokument_id
            $oldInspeksiList = Inspeksi::where('permohonan_id', $this->permohonanId)
                ->where('created_by', $this->createdBy)
                ->whereNull('dokument_id')
                ->whereNull('deleted_at')
                ->where('id', '!=', $newInspeksi->id) // Jangan hapus data yang baru saja ditemukan
                ->get();

            if ($oldInspeksiList->isEmpty()) {
                Log::info('CleanupInspeksiDataJob: Tidak ditemukan data inspeksi lama tanpa dokument_id', [
                    'permohonan_id' => $this->permohonanId,
                    'created_by' => $this->createdBy
                ]);
                DB::commit();
                return;
            }

            $deletedCount = 0;
            foreach ($oldInspeksiList as $oldInspeksi) {
                // Soft delete data lama
                $oldInspeksi->delete(); // Menggunakan soft delete karena model menggunakan SoftDeletes trait
                
                Log::info('CleanupInspeksiDataJob: Data inspeksi lama berhasil di-soft delete', [
                    'old_inspeksi_id' => $oldInspeksi->id,
                    'permohonan_id' => $oldInspeksi->permohonan_id,
                    'created_by' => $oldInspeksi->created_by,
                    'deleted_at' => now()->toDateTimeString()
                ]);
                
                $deletedCount++;
            }

            DB::commit();

            Log::info('CleanupInspeksiDataJob: Proses cleanup selesai', [
                'permohonan_id' => $this->permohonanId,
                'created_by' => $this->createdBy,
                'deleted_count' => $deletedCount,
                'new_inspeksi_id' => $newInspeksi->id
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('CleanupInspeksiDataJob: Terjadi error saat proses cleanup', [
                'permohonan_id' => $this->permohonanId,
                'created_by' => $this->createdBy,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            throw $e;
        }
    }

    /**
     * Handle a job failure.
     *
     * @param \Throwable $exception
     * @return void
     */
    public function failed(\Throwable $exception): void
    {
        Log::error('CleanupInspeksiDataJob: Job gagal dieksekusi', [
            'permohonan_id' => $this->permohonanId,
            'created_by' => $this->createdBy,
            'error' => $exception->getMessage(),
            'trace' => $exception->getTraceAsString()
        ]);
    }
}