<?php

namespace Tests\Feature;

use App\Models\Kategori;
use App\Models\ObatMasuk;
use App\Models\Satuan;
use App\Models\User;
use Tests\DatabaseTestCase;

class KadaluarsaTest extends DatabaseTestCase
{
    private User $user;
    private Kategori $kategori;
    private Satuan $satuan;
    private int $batchSeq = 0;

    protected function setUp(): void
    {
        parent::setUp();
        $this->batchSeq = 0;
        $this->user     = User::factory()->create(['role' => 'apoteker']);
        $this->kategori = Kategori::create(['nama' => 'Antibiotik']);
        $this->satuan   = Satuan::create(['nama' => 'Tablet']);
        $this->actingAs($this->user);
    }

    private function createObat(string $namaObat, string $kadaluarsa, int $stok = 10): ObatMasuk
    {
        $this->batchSeq++;
        return ObatMasuk::create([
            'nama_obat'          => $namaObat,
            'kategori_id'        => $this->kategori->id,
            'satuan_id'          => $this->satuan->id,
            'kode_batch'         => 'BTH-' . str_pad($this->batchSeq, 3, '0', STR_PAD_LEFT),
            'stok'               => $stok,
            'tanggal_penerimaan' => now()->subYear()->toDateString(),
            'tanggal_kadaluarsa' => $kadaluarsa,
            'user_id'            => $this->user->id,
        ]);
    }

    // ─────────────────────────────────────────
    // index
    // ─────────────────────────────────────────

    public function test_index_returns_200(): void
    {
        $response = $this->get(route('kadaluarsa.index'));
        $response->assertStatus(200);
    }

    public function test_index_redirects_guest(): void
    {
        auth()->logout();
        $response = $this->get(route('kadaluarsa.index'));
        $response->assertRedirect(route('login'));
    }

    public function test_index_shows_only_obat_expiring_within_120_days(): void
    {
        $this->createObat('ObatKritis',  now()->addDays(15)->toDateString());  // ≤ 30 hari ✓
        $this->createObat('ObatWaspada', now()->addDays(110)->toDateString()); // ≤ 120 hari ✓
        $this->createObat('ObatAman',    now()->addDays(130)->toDateString()); // > 120 hari ✗

        $response = $this->get(route('kadaluarsa.index'));
        $data     = $response->viewData('obatKadaluarsa');

        $names = $data->pluck('nama_obat')->toArray();
        $this->assertContains('ObatKritis', $names);
        $this->assertContains('ObatWaspada', $names);
        $this->assertNotContains('ObatAman', $names);
    }

    // ─────────────────────────────────────────
    // Filter expired
    // ─────────────────────────────────────────

    public function test_filter_expired_shows_only_past_expiry(): void
    {
        $this->createObat('ObatExpired',      now()->subDay()->toDateString());
        $this->createObat('ObatBelumExpired', now()->addDays(20)->toDateString());

        $response = $this->get(route('kadaluarsa.index', ['filter' => 'expired']));
        $data     = $response->viewData('obatKadaluarsa');

        $names = $data->pluck('nama_obat')->toArray();
        $this->assertContains('ObatExpired', $names);
        $this->assertNotContains('ObatBelumExpired', $names);
    }

    // ─────────────────────────────────────────
    // Filter 30
    // ─────────────────────────────────────────

    public function test_filter_30_shows_obat_expiring_within_30_days(): void
    {
        $this->createObat('ObatKritis',  now()->addDays(20)->toDateString()); // ≤ 30 hari ✓
        $this->createObat('ObatWaspada', now()->addDays(50)->toDateString()); // > 30 hari ✗

        $response = $this->get(route('kadaluarsa.index', ['filter' => '30']));
        $data     = $response->viewData('obatKadaluarsa');

        $names = $data->pluck('nama_obat')->toArray();
        $this->assertContains('ObatKritis', $names);
        $this->assertNotContains('ObatWaspada', $names);
    }

    // ─────────────────────────────────────────
    // Filter 120
    // ─────────────────────────────────────────

    public function test_filter_120_shows_obat_expiring_within_120_days(): void
    {
        $this->createObat('ObatDalamRange', now()->addDays(110)->toDateString()); // ≤ 120 hari ✓
        $this->createObat('ObatAman',       now()->addDays(130)->toDateString()); // > 120 hari ✗

        $response = $this->get(route('kadaluarsa.index', ['filter' => '120']));
        $data     = $response->viewData('obatKadaluarsa');

        $names = $data->pluck('nama_obat')->toArray();
        $this->assertContains('ObatDalamRange', $names);
        $this->assertNotContains('ObatAman', $names);
    }

    // ─────────────────────────────────────────
    // Filter all (default)
    // ─────────────────────────────────────────

    public function test_filter_all_shows_all_obat_within_120_days(): void
    {
        $this->createObat('ObatExpired', now()->subDays(5)->toDateString());  // expired ✓
        $this->createObat('ObatKritis',  now()->addDays(25)->toDateString()); // ≤ 30 hari ✓
        $this->createObat('ObatWaspada', now()->addDays(110)->toDateString()); // ≤ 120 hari ✓

        $response = $this->get(route('kadaluarsa.index', ['filter' => 'all']));
        $data     = $response->viewData('obatKadaluarsa');

        $names = $data->pluck('nama_obat')->toArray();
        $this->assertContains('ObatExpired', $names);
        $this->assertContains('ObatKritis', $names);
        $this->assertContains('ObatWaspada', $names);
    }

    public function test_passes_filter_variable_to_view(): void
    {
        $response = $this->get(route('kadaluarsa.index', ['filter' => 'expired']));
        $response->assertViewHas('filter', 'expired');
    }
}
