<?php

namespace Tests\Feature;

use App\Models\Billing;
use App\Models\Customer;
use App\Models\InventoryItem;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

class CustomerPortalInventoryTest extends TestCase
{
    use RefreshDatabase;

    public function test_customer_can_open_payment_only_portal_with_configured_identifier(): void
    {
        Setting::create(['key' => 'customer_portal.identifier_mode', 'value' => 'code_or_pppoe']);
        Setting::create(['key' => 'customer_portal.verification_mode', 'value' => 'none']);
        $customer = Customer::create(['customer_code' => 'LOGIN-100', 'name' => 'Portal Customer', 'contact_phone' => '01700000009', 'ip_address' => 'ruman@pppoe', 'monthly_bill' => 700, 'status' => 1]);
        Billing::create(['customer_id' => $customer->id, 'amount' => 700, 'due_amount' => 700, 'status' => 'pending']);

        $this->post(route('customer.login.identify'), ['identifier' => 'ruman@pppoe'])
            ->assertRedirect(route('portal.dashboard'))
            ->assertSessionHas('customer_portal_customer_id', $customer->id);
        $this->get(route('portal.dashboard'))->assertOk()->assertSee('Portal Customer')->assertDontSee('Assigned equipment')->assertDontSee('Account Statement');
    }

    public function test_customer_portal_only_displays_linked_customer_data(): void
    {
        $role = Role::create(['name' => 'Customer']);
        $own = Customer::create(['customer_code' => 'PORTAL-1', 'name' => 'Own Customer', 'contact_phone' => '01700000001', 'monthly_bill' => 500, 'status' => 1]);
        $other = Customer::create(['customer_code' => 'PRIVATE-2', 'name' => 'Other Private Customer', 'contact_phone' => '01700000002', 'monthly_bill' => 900, 'status' => 1]);
        Billing::create(['customer_id' => $own->id, 'amount' => 500, 'due_amount' => 500, 'status' => 'pending']);
        Billing::create(['customer_id' => $other->id, 'amount' => 900, 'due_amount' => 900, 'status' => 'pending']);
        $user = User::factory()->create(['customer_id' => $own->id]);
        $user->assignRole($role);

        $this->actingAs($user)->get(route('portal.dashboard'))->assertOk()->assertSee('Own Customer')->assertSee('500.00')->assertDontSee('Other Private Customer')->assertDontSee('900.00');
        $this->actingAs($user)->get(route('portal.dashboard'))->assertOk()->assertDontSee('Account Statement')->assertDontSee('Assigned equipment');
    }

    public function test_inventory_prevents_negative_stock_and_records_customer_issue(): void
    {
        foreach (['inventory.view', 'inventory.manage'] as $name) {
            Permission::create(['name' => $name]);
        }
        $role = Role::create(['name' => 'Admin']);
        $role->syncPermissions(['inventory.view', 'inventory.manage']);
        $admin = User::factory()->create();
        $admin->assignRole($role);
        $customer = Customer::create(['customer_code' => 'INV-1', 'name' => 'Inventory Customer', 'contact_phone' => '01700000003', 'monthly_bill' => 500, 'status' => 1]);
        $item = InventoryItem::create(['sku' => 'ONU-1', 'name' => 'ONU', 'stock_quantity' => 2, 'minimum_stock' => 1]);

        $payload = ['inventory_item_id' => $item->id, 'type' => 'issue', 'customer_id' => $customer->id, 'quantity' => 1, 'transaction_date' => now()->toDateString()];
        $this->actingAs($admin)->post(route('admin.inventory.transaction'), $payload)->assertRedirect();
        $this->assertEquals('1.00', $item->fresh()->stock_quantity);
        $this->assertDatabaseHas('inventory_transactions', ['inventory_item_id' => $item->id, 'customer_id' => $customer->id, 'type' => 'issue']);

        $this->actingAs($admin)->from(route('admin.inventory.index'))->post(route('admin.inventory.transaction'), array_merge($payload, ['quantity' => 5]))->assertSessionHasErrors('quantity');
        $this->assertEquals('1.00', $item->fresh()->stock_quantity);
    }
}
