<?php

namespace App\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\Mail;
use Illuminate\Support\Facades\Log;
use App\Mail\MuscabInvitationEmail;
use App\Models\Anggota; // Pastikan ini diimpor

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

    // Maksimal percobaan pengiriman job
    public $tries = 3;
    // Jeda waktu (dalam detik) sebelum mencoba kembali job yang gagal
    public $retryAfter = 60;

    public $anggota;
    public $qrCodeUrl;

    /**
     * Buat instance job baru.
     *
     * @param  \App\Models\Anggota  $anggota
     * @param  string|null  $qrCodeUrl
     * @return void
     */
    public function __construct($anggota, $qrCodeUrl = null)
    {
        $this->anggota = $anggota;
        $this->qrCodeUrl = $qrCodeUrl;
    }

    /**
     * Jalankan job.
     *
     * @return void
     */
    public function handle()
    {
        // Ambil ulang data anggota dari database untuk memastikan kita bekerja dengan data terbaru.
        // Ini penting karena data anggota mungkin telah diubah di tempat lain setelah job didispatch.
        $anggota = Anggota::find($this->anggota->id);

        // Jika anggota tidak ditemukan (misal, telah dihapus dari database),
        // catat peringatan dan hentikan eksekusi job.
        if (!$anggota) {
            Log::warning("Anggota dengan ID {$this->anggota->id} tidak ditemukan saat mencoba mengirim email.");
            return;
        }

        try {
            // Coba kirim email menggunakan Mailable MuscabInvitationEmail
            Mail::to($anggota->email)->send(new MuscabInvitationEmail($anggota, $this->qrCodeUrl));

            // Jika pengiriman email berhasil, perbarui status di database
            $anggota->email_sent = true;
            $anggota->email_error_log = null; // Hapus pesan error sebelumnya jika ada
            $anggota->save();

            // Catat log informasi bahwa email berhasil dikirim
            Log::info("Email berhasil dikirim ke {$anggota->email}");
        } catch (\Exception $e) {
            // Jika terjadi kesalahan saat pengiriman email, perbarui status di database
            $anggota->email_sent = false;
            $anggota->email_error_log = $e->getMessage(); // Simpan pesan error
            $anggota->save();

            // Catat log error tentang kegagalan pengiriman email
            Log::error("Email Error ke {$anggota->email}: " . $e->getMessage());

            // Lempar kembali exception agar Laravel dapat menangani job yang gagal.
            // Ini akan memicu mekanisme retry atau mencatat job di tabel 'failed_jobs'
            // setelah semua percobaan habis.
            throw $e;
        }
    }
}
