<?php

namespace Tests\Unit;

use App\Models\Resep;
use App\Models\User;
use Tests\DatabaseTestCase;

class ResepModelTest extends DatabaseTestCase
{

    // ─────────────────────────────────────────
    // getStatusColorAttribute()
    // ─────────────────────────────────────────

    public function test_status_color_is_terkirim_when_status_selesai(): void
    {
        $resep = new Resep(['status' => 'selesai']);
        $this->assertEquals('terkirim', $resep->status_color);
    }

    public function test_status_color_is_proses_when_status_proses(): void
    {
        $resep = new Resep(['status' => 'proses']);
        $this->assertEquals('proses', $resep->status_color);
    }

    public function test_status_color_is_dibatalkan_when_status_dibatalkan(): void
    {
        $resep = new Resep(['status' => 'dibatalkan']);
        $this->assertEquals('dibatalkan', $resep->status_color);
    }

    public function test_status_color_defaults_to_proses_for_unknown_status(): void
    {
        $resep = new Resep(['status' => 'unknown']);
        $this->assertEquals('proses', $resep->status_color);
    }

    // ─────────────────────────────────────────
    // generateNoResep() - requires DB
    // ─────────────────────────────────────────

    public function test_generate_no_resep_starts_with_rsp_prefix(): void
    {
        $noResep = Resep::generateNoResep();
        $this->assertStringStartsWith('RSP-', $noResep);
    }

    public function test_generate_no_resep_contains_today_date(): void
    {
        $today = now()->format('Ymd');
        $noResep = Resep::generateNoResep();
        $this->assertStringContainsString($today, $noResep);
    }

    public function test_generate_no_resep_starts_at_0001_when_no_resep_today(): void
    {
        // Tidak ada resep hari ini
        $today = now()->format('Ymd');
        $noResep = Resep::generateNoResep();
        $this->assertEquals("RSP-{$today}-0001", $noResep);
    }

    public function test_generate_no_resep_increments_when_resep_exists_today(): void
    {
        $user = User::factory()->create();

        // Buat resep pertama hari ini
        Resep::create([
            'no_resep'        => Resep::generateNoResep(),
            'user_id'         => $user->id,
            'nama_pasien'     => 'Pasien A',
            'tanggal_resep'   => now()->toDateString(),
            'diagnosa'        => 'Flu',
            'status'          => 'proses',
            'nama_dokter'     => 'Dokter A',
            'jenis_penjamin'  => 'umum',
            'jenis_layanan'   => 'BP',
            'jenis_kelamin'   => 'L',
            'umur_pasien'     => 30,
            'berat_badan'     => 60,
            'is_read'         => false,
        ]);

        $today = now()->format('Ymd');
        $noResep = Resep::generateNoResep();
        $this->assertEquals("RSP-{$today}-0002", $noResep);
    }

    // ─────────────────────────────────────────
    // scopeUnread()
    // ─────────────────────────────────────────

    public function test_scope_unread_only_returns_unread_reseps(): void
    {
        $user = User::factory()->create();

        Resep::create([
            'no_resep'       => 'RSP-TEST-0001',
            'user_id'        => $user->id,
            'nama_pasien'    => 'Pasien Unread',
            'tanggal_resep'  => now()->toDateString(),
            'diagnosa'       => 'Flu',
            'status'         => 'proses',
            'nama_dokter'    => 'Dokter A',
            'jenis_penjamin' => 'umum',
            'jenis_layanan'  => 'BP',
            'jenis_kelamin'  => 'L',
            'umur_pasien'    => 25,
            'berat_badan'    => 55,
            'is_read'        => false,
        ]);

        Resep::create([
            'no_resep'       => 'RSP-TEST-0002',
            'user_id'        => $user->id,
            'nama_pasien'    => 'Pasien Read',
            'tanggal_resep'  => now()->toDateString(),
            'diagnosa'       => 'Batuk',
            'status'         => 'proses',
            'nama_dokter'    => 'Dokter B',
            'jenis_penjamin' => 'umum',
            'jenis_layanan'  => 'BP',
            'jenis_kelamin'  => 'P',
            'umur_pasien'    => 30,
            'berat_badan'    => 50,
            'is_read'        => true,
        ]);

        $unread = Resep::unread()->get();
        $this->assertCount(1, $unread);
        $this->assertEquals('Pasien Unread', $unread->first()->nama_pasien);
    }

    // ─────────────────────────────────────────
    // markAsRead()
    // ─────────────────────────────────────────

    public function test_mark_as_read_sets_is_read_to_true(): void
    {
        $user = User::factory()->create();

        $resep = Resep::create([
            'no_resep'       => 'RSP-TEST-0010',
            'user_id'        => $user->id,
            'nama_pasien'    => 'Pasien Test',
            'tanggal_resep'  => now()->toDateString(),
            'diagnosa'       => 'Flu',
            'status'         => 'proses',
            'nama_dokter'    => 'Dokter X',
            'jenis_penjamin' => 'umum',
            'jenis_layanan'  => 'BP',
            'jenis_kelamin'  => 'L',
            'umur_pasien'    => 25,
            'berat_badan'    => 60,
            'is_read'        => false,
        ]);

        $resep->markAsRead();
        $resep->refresh();

        $this->assertTrue($resep->is_read);
    }

    public function test_mark_as_read_does_not_re_update_if_already_read(): void
    {
        $user = User::factory()->create();

        $resep = Resep::create([
            'no_resep'       => 'RSP-TEST-0011',
            'user_id'        => $user->id,
            'nama_pasien'    => 'Pasien Read',
            'tanggal_resep'  => now()->toDateString(),
            'diagnosa'       => 'Flu',
            'status'         => 'proses',
            'nama_dokter'    => 'Dokter Y',
            'jenis_penjamin' => 'umum',
            'jenis_layanan'  => 'BP',
            'jenis_kelamin'  => 'P',
            'umur_pasien'    => 20,
            'berat_badan'    => 45,
            'is_read'        => true,
        ]);

        // Panggil markAsRead() ketika sudah true — tidak boleh error
        $resep->markAsRead();
        $resep->refresh();

        $this->assertTrue($resep->is_read);
    }

    // ─────────────────────────────────────────
    // Relationships
    // ─────────────────────────────────────────

    public function test_resep_belongs_to_user(): void
    {
        $resep = new Resep();
        $this->assertInstanceOf(
            \Illuminate\Database\Eloquent\Relations\BelongsTo::class,
            $resep->user()
        );
    }

    public function test_resep_has_many_items(): void
    {
        $resep = new Resep();
        $this->assertInstanceOf(
            \Illuminate\Database\Eloquent\Relations\HasMany::class,
            $resep->items()
        );
    }

    // ─────────────────────────────────────────
    // Fillable & Casts
    // ─────────────────────────────────────────

    public function test_resep_is_read_is_cast_as_boolean(): void
    {
        $resep = new Resep();
        $casts = $resep->getCasts();
        $this->assertEquals('boolean', $casts['is_read']);
    }

    public function test_resep_tanggal_resep_is_cast_as_date(): void
    {
        $resep = new Resep();
        $casts = $resep->getCasts();
        $this->assertEquals('date', $casts['tanggal_resep']);
    }
}
