<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Models\User;
use App\Models\Outlet;
use App\Models\Product;
use App\Models\Ingredient;
use App\Models\OutletIngredient;
use App\Models\Recipe;
use App\Models\Transaction;
use App\Models\TransactionItem;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PosTransactionTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }

    public function test_admin_can_delete_transaction_and_revert_stock(): void
    {
        $admin = User::where('email', 'admin@example.com')->first();
        $this->assertNotNull($admin);

        // 1. Create a specific outlet
        $outlet = Outlet::create(['name' => 'Outlet Test']);

        // 2. Create ingredient and set stock to 100
        $ingredient = Ingredient::create(['name' => 'Susu Cair', 'unit' => 'ml']);
        $outletIngredient = OutletIngredient::create([
            'outlet_id' => $outlet->id,
            'ingredient_id' => $ingredient->id,
            'stock_qty' => 100.0,
            'threshold_qty' => 20.0,
        ]);

        // 3. Create product with recipe
        $product = Product::create([
            'name' => 'Latte Test',
            'price' => 25000,
            'category' => 'Coffee',
            'is_active' => true,
        ]);

        Recipe::create([
            'product_id' => $product->id,
            'ingredient_id' => $ingredient->id,
            'usage_qty' => 10.0, // 10ml per latte
        ]);

        // 4. Create Transaction representing checkout (2 Lattes sold)
        // Stock should have been reduced manually (or we mock the state: 2 Latte sold, meaning stock was reduced by 20ml, so current stock is 80ml)
        $outletIngredient->update(['stock_qty' => 80.0]);

        $transaction = Transaction::create([
            'transaction_number' => 'TXN-TEST-12345',
            'outlet_id' => $outlet->id,
            'user_id' => $admin->id,
            'total_amount' => 50000.0,
            'tax_amount' => 0.0,
            'service_charge_amount' => 0.0,
            'payment_method' => 'cash',
            'status' => 'success',
        ]);

        TransactionItem::create([
            'transaction_id' => $transaction->id,
            'product_id' => $product->id,
            'qty' => 2,
            'price' => 25000.0,
            'subtotal' => 50000.0,
        ]);

        // 5. Delete transaction via endpoint
        $response = $this->actingAs($admin)
            ->delete(route('transactions.destroy', $transaction->id));

        $response->assertRedirect();
        
        // 6. Verify database records
        $this->assertDatabaseMissing('transactions', ['id' => $transaction->id]);
        $this->assertDatabaseMissing('transaction_items', ['transaction_id' => $transaction->id]);

        // 7. Verify stock has been reverted (80ml + (2 qty * 10ml usage) = 100ml)
        $outletIngredient->refresh();
        $this->assertEquals(100.0, (float)$outletIngredient->stock_qty);
    }

    public function test_cashier_cannot_delete_transaction(): void
    {
        $cashier = User::where('email', 'cashier@example.com')->first();
        if (!$cashier) {
            $cashier = User::factory()->create();
            $cashier->assignRole('Kasir');
        }

        $outlet = Outlet::create(['name' => 'Outlet Test 2']);
        $transaction = Transaction::create([
            'transaction_number' => 'TXN-TEST-56789',
            'outlet_id' => $outlet->id,
            'user_id' => $cashier->id,
            'total_amount' => 10000.0,
            'tax_amount' => 0.0,
            'service_charge_amount' => 0.0,
            'payment_method' => 'cash',
            'status' => 'success',
        ]);

        $response = $this->actingAs($cashier)
            ->delete(route('transactions.destroy', $transaction->id));

        // It should reject or redirect back with unauthorized access
        $response->assertSessionHas('error');
    }

    public function test_can_load_printable_pos_receipt(): void
    {
        $admin = User::where('email', 'admin@example.com')->first();
        $this->assertNotNull($admin);

        $outlet = Outlet::create(['name' => 'Outlet Test 3']);
        $transaction = Transaction::create([
            'transaction_number' => 'TXN-TEST-33333',
            'outlet_id' => $outlet->id,
            'user_id' => $admin->id,
            'total_amount' => 20000.0,
            'tax_amount' => 0.0,
            'service_charge_amount' => 0.0,
            'payment_method' => 'cash',
            'status' => 'success',
        ]);

        $response = $this->actingAs($admin)
            ->get(route('transactions.print', $transaction->id));

        $response->assertOk();
    }
}
