<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use PhpMqtt\Client\MqttClient;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\IotMode;

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

    protected $bookId;
    protected $userId;

    /**
     * Maksimal retry
     */
    public $tries = 3;

    /**
     * Timeout job
     */
    public $timeout = 30;

    public function __construct($bookId, $userId)
    {
        $this->bookId = $bookId;
        $this->userId = $userId;
    }

    public function handle(): void
    {
        try {

            /*
            |--------------------------------------------------------------------------
            | Ambil Data Buku
            |--------------------------------------------------------------------------
            */

            $book = DB::table('koleksis')
                ->where('biblio_id', $this->bookId)
                ->first();

            if (!$book) {
                Log::error('Buku tidak ditemukan');
                return;
            }

            $judulBuku = $book->judul_koleksi
                ?? $book->title
                ?? 'Buku';

            /*
            |--------------------------------------------------------------------------
            | Cegah Double Peminjaman
            |--------------------------------------------------------------------------
            */

            $existing = DB::table('borrow_transactions')
                ->where('koleksi_id', $this->bookId)
                ->where('status', 'dipinjam')
                ->first();

            if ($existing) {

                Log::warning('Buku sudah dipinjam');

                $this->publishMqtt('rfid/status', 'failed');

                return;
            }

            /*
            |--------------------------------------------------------------------------
            | Insert Transaksi
            |--------------------------------------------------------------------------
            */

            DB::table('borrow_transactions')->insert([
                'anggota_id'      => $this->userId,
                'koleksi_id'      => $this->bookId,
                'tanggal_pinjam'  => now(),
                'tanggal_kembali' => now()->addDays(7),
                'status'          => 'dipinjam',
                'created_at'      => now(),
                'updated_at'      => now()
            ]);

            /*
            |--------------------------------------------------------------------------
            | Update State IoT
            |--------------------------------------------------------------------------
            */

            IotMode::where('id', 1)->update([
                'mode' => 'success_loan'
            ]);

            /*
            |--------------------------------------------------------------------------
            | MQTT Publish
            |--------------------------------------------------------------------------
            */

            $this->publishMqtt('rfid/status', 'finish');

            $this->publishMqtt(
                'peminjaman/user/' . $this->userId,
                [
                    'status' => 'dipinjam',
                    'message' => "Buku [$judulBuku] berhasil dipinjam"
                ]
            );

            /*
            |--------------------------------------------------------------------------
            | Reset ke Standby
            |--------------------------------------------------------------------------
            */

            sleep(2);

            IotMode::where('id', 1)->update([
                'mode' => 'standby',
                'book_id' => null,
                'user_id' => null
            ]);

            $this->publishMqtt('rfid/mode', 'standby');
            $this->publishMqtt('rfid/status', 'idle');

            Log::info('Peminjaman berhasil diproses via queue');

        } catch (\Exception $e) {

            Log::error('Queue Peminjaman Error: ' . $e->getMessage());

            IotMode::where('id', 1)->update([
                'mode' => 'wait'
            ]);

            $this->publishMqtt('rfid/status', 'failed');
        }
    }

    /*
    |--------------------------------------------------------------------------
    | Helper MQTT
    |--------------------------------------------------------------------------
    */

    private function publishMqtt($topic, $message): void
    {
        try {

            $mqtt = new MqttClient(
                '127.0.0.1',
                1883,
                'laravel-job-' . uniqid()
            );

            $mqtt->connect();

            $payload = is_array($message)
                ? json_encode($message)
                : (string) $message;

            $mqtt->publish($topic, $payload, 0);

            $mqtt->disconnect();

        } catch (\Exception $e) {

            Log::error('MQTT Publish Error: ' . $e->getMessage());
        }
    }
}

