<?php

namespace Tests\Feature\Api;

use App\Models\Ingredient;
use App\Models\PurchaseOrder;
use App\Models\StockLedger;

class InventoryManagementTest extends ApiTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        $this->createAuthenticatedUser();
    }

    // ==================== STOCK MANAGEMENT TESTS ====================

    public function test_can_view_branch_stock(): void
    {
        $ingredient = Ingredient::create(['name' => 'Milk', 'unit' => 'liters', 'cost_per_unit' => 5.00, 'is_active' => true]);
        StockLedger::create([
            'branch_id' => $this->branch->id,
            'ingredient_id' => $ingredient->id,
            'quantity' => 100,
        ]);

        $response = $this->getJson("/api/v1/branches/{$this->branch->id}/inventory/stock");

        $this->assertSuccessResponse($response);
    }

    public function test_can_view_ingredient_stock(): void
    {
        $ingredient = Ingredient::create(['name' => 'Sugar', 'unit' => 'kg', 'cost_per_unit' => 10.00, 'is_active' => true]);
        StockLedger::create([
            'branch_id' => $this->branch->id,
            'ingredient_id' => $ingredient->id,
            'quantity' => 50,
        ]);

        $response = $this->getJson("/api/v1/branches/{$this->branch->id}/inventory/stock/{$ingredient->id}");

        $this->assertSuccessResponse($response);
    }

    public function test_can_add_stock(): void
    {
        $ingredient = Ingredient::create(['name' => 'Flour', 'unit' => 'kg', 'cost_per_unit' => 15.00, 'is_active' => true]);

        $response = $this->postJson("/api/v1/branches/{$this->branch->id}/inventory/add-stock", [
            'ingredient_id' => $ingredient->id,
            'quantity' => 25,
            'notes' => 'Initial stock',
        ]);

        $this->assertSuccessResponse($response, 201);
        $this->assertDatabaseHas('stock_ledgers', [
            'branch_id' => $this->branch->id,
            'ingredient_id' => $ingredient->id,
        ]);
    }

    public function test_can_deduct_stock(): void
    {
        $ingredient = Ingredient::create(['name' => 'Butter', 'unit' => 'kg', 'cost_per_unit' => 20.00, 'is_active' => true]);
        StockLedger::create([
            'branch_id' => $this->branch->id,
            'ingredient_id' => $ingredient->id,
            'quantity' => 100,
        ]);

        $response = $this->postJson("/api/v1/branches/{$this->branch->id}/inventory/deduct-stock", [
            'ingredient_id' => $ingredient->id,
            'quantity' => 10,
            'notes' => 'Used in production',
        ]);

        $this->assertSuccessResponse($response, 201);
    }

    public function test_can_adjust_stock(): void
    {
        $ingredient = Ingredient::create(['name' => 'Cream', 'unit' => 'liters', 'cost_per_unit' => 25.00, 'is_active' => true]);
        StockLedger::create([
            'branch_id' => $this->branch->id,
            'ingredient_id' => $ingredient->id,
            'quantity' => 50,
        ]);

        $response = $this->postJson("/api/v1/branches/{$this->branch->id}/inventory/adjust-stock", [
            'ingredient_id' => $ingredient->id,
            'new_quantity' => 45,
            'notes' => 'Physical count adjustment',
        ]);

        $this->assertSuccessResponse($response);
    }

    public function test_can_record_waste(): void
    {
        $ingredient = Ingredient::create(['name' => 'Ice Cream Mix', 'unit' => 'kg', 'cost_per_unit' => 30.00, 'is_active' => true]);
        StockLedger::create([
            'branch_id' => $this->branch->id,
            'ingredient_id' => $ingredient->id,
            'quantity' => 100,
        ]);

        $response = $this->postJson("/api/v1/branches/{$this->branch->id}/inventory/record-waste", [
            'ingredient_id' => $ingredient->id,
            'quantity' => 5,
            'notes' => 'Spoilage',
        ]);

        $this->assertSuccessResponse($response, 201);
    }

    public function test_can_view_low_stock(): void
    {
        $ingredient = Ingredient::create([
            'name' => 'Low Stock Item',
            'unit' => 'kg',
            'cost_per_unit' => 10.00,
            'reorder_level' => 20,
            'is_active' => true,
        ]);
        StockLedger::create([
            'branch_id' => $this->branch->id,
            'ingredient_id' => $ingredient->id,
            'quantity' => 5,
        ]);

        $response = $this->getJson("/api/v1/branches/{$this->branch->id}/inventory/low-stock");

        $this->assertSuccessResponse($response);
    }

    public function test_can_view_transactions(): void
    {
        $response = $this->getJson("/api/v1/branches/{$this->branch->id}/inventory/transactions");

        $this->assertSuccessResponse($response);
    }

    // ==================== PURCHASE ORDER TESTS ====================

    public function test_can_list_purchase_orders(): void
    {
        $response = $this->getJson('/api/v1/purchase-orders');

        $this->assertSuccessResponse($response);
    }

    public function test_can_create_purchase_order(): void
    {
        $ingredient = Ingredient::create(['name' => 'Vanilla', 'unit' => 'kg', 'cost_per_unit' => 50.00, 'is_active' => true]);

        $response = $this->postJson('/api/v1/purchase-orders', [
            'branch_id' => $this->branch->id,
            'supplier_name' => 'Test Supplier',
            'expected_date' => now()->addDays(7)->toDateString(),
            'notes' => 'Test order',
            'items' => [
                [
                    'ingredient_id' => $ingredient->id,
                    'quantity_ordered' => 10,
                    'unit_cost' => 50.00,
                ],
            ],
        ]);

        $this->assertSuccessResponse($response, 201);
        $this->assertDatabaseHas('purchase_orders', [
            'branch_id' => $this->branch->id,
            'supplier_name' => 'Test Supplier',
        ]);
    }

    public function test_can_show_purchase_order(): void
    {
        $po = PurchaseOrder::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'po_number' => 'PO-001',
            'supplier_name' => 'Supplier',
            'status' => 'pending',
            'total_amount' => 500.00,
        ]);

        $response = $this->getJson("/api/v1/purchase-orders/{$po->id}");

        $this->assertSuccessResponse($response);
    }

    public function test_can_update_purchase_order_status(): void
    {
        $po = PurchaseOrder::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'po_number' => 'PO-002',
            'supplier_name' => 'Supplier',
            'status' => 'pending',
            'total_amount' => 500.00,
        ]);

        $response = $this->putJson("/api/v1/purchase-orders/{$po->id}/status", [
            'status' => 'approved',
        ]);

        $this->assertSuccessResponse($response);
        $this->assertDatabaseHas('purchase_orders', ['id' => $po->id, 'status' => 'approved']);
    }

    public function test_can_receive_purchase_order(): void
    {
        $ingredient = Ingredient::create(['name' => 'Test Ingredient', 'unit' => 'kg', 'cost_per_unit' => 50.00, 'is_active' => true]);
        $po = PurchaseOrder::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'po_number' => 'PO-003',
            'supplier_name' => 'Supplier',
            'status' => 'approved',
            'total_amount' => 500.00,
        ]);
        $poItem = $po->items()->create([
            'ingredient_id' => $ingredient->id,
            'quantity_ordered' => 10,
            'unit_cost' => 50.00,
            'total_cost' => 500.00,
        ]);

        $response = $this->postJson("/api/v1/purchase-orders/{$po->id}/receive", [
            'items' => [
                [
                    'item_id' => $poItem->id,
                    'quantity_received' => 10,
                ],
            ],
        ]);

        $this->assertSuccessResponse($response);
        $this->assertDatabaseHas('purchase_orders', ['id' => $po->id, 'status' => 'received']);
    }

    public function test_can_cancel_purchase_order(): void
    {
        $po = PurchaseOrder::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'po_number' => 'PO-004',
            'supplier_name' => 'Supplier',
            'status' => 'pending',
            'total_amount' => 500.00,
        ]);

        $response = $this->postJson("/api/v1/purchase-orders/{$po->id}/cancel");

        $this->assertSuccessResponse($response);
        $this->assertDatabaseHas('purchase_orders', ['id' => $po->id, 'status' => 'cancelled']);
    }

    public function test_can_list_purchase_orders_by_branch(): void
    {
        PurchaseOrder::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'po_number' => 'PO-005',
            'supplier_name' => 'Supplier',
            'status' => 'pending',
            'total_amount' => 500.00,
        ]);

        $response = $this->getJson("/api/v1/purchase-orders/branch/{$this->branch->id}");

        $this->assertSuccessResponse($response);
        $this->assertCount(1, $response->json('data'));
    }

    public function test_can_list_purchase_orders_by_status(): void
    {
        PurchaseOrder::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'po_number' => 'PO-006',
            'supplier_name' => 'Supplier',
            'status' => 'pending',
            'total_amount' => 500.00,
        ]);

        $response = $this->getJson("/api/v1/purchase-orders/branch/{$this->branch->id}/status/pending");

        $this->assertSuccessResponse($response);
    }

    // ==================== STOCK ALERTS TESTS ====================

    public function test_can_view_stock_alerts(): void
    {
        $response = $this->getJson("/api/v1/branches/{$this->branch->id}/inventory/alerts");

        $this->assertSuccessResponse($response);
    }
}
