<?php

namespace Tests\Feature;

use App\Models\Order;
use App\Models\Product;
use App\Models\User;
use App\Services\ProfitService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PosOrderProfitTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }

    public function test_pos_order_calculates_profit_correctly()
    {
        // Create a staff user for POS access
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        // Create a customer
        $customer = User::factory()->create();

        // Create a product with purchase price
        $product = Product::factory()->create([
            'name' => 'Test Product',
            'price' => 100.00,
            'purchase_price' => 60.00,
            'current_stock' => 10,
        ]);

        // Act as staff user
        $this->actingAs($staff);

        // Create POS order
        $response = $this->postJson('/admin/api/pos/orders', [
            'user_id' => $customer->id,
            'items' => [
                [
                    'product_id' => $product->id,
                    'qty' => 2,
                    'price' => 100.00,
                ]
            ],
            'payment_method' => 'cash',
            'subtotal' => 200.00,
            'discount_total' => 0,
            'tax_total' => 0,
            'total_payable' => 200.00,
        ]);

        $response->assertStatus(201);
        $responseData = $response->json();

        // Verify order was created
        $this->assertTrue($responseData['success']);
        $orderId = $responseData['data']['order_id'];

        // Verify order exists and is POS order
        $order = Order::find($orderId);
        $this->assertNotNull($order);
        $this->assertEquals('pos', $order->source);
        $this->assertEquals($staff->id, $order->staff_id);

        // Verify order item has purchase price for profit calculation
        $orderItem = $order->items->first();
        $this->assertNotNull($orderItem);
        $this->assertEquals($product->purchase_price, $orderItem->purchase_price);

        // Verify profit calculation
        $expectedProfit = ($orderItem->price - $orderItem->purchase_price) * $orderItem->qty;
        $this->assertEquals($expectedProfit, $orderItem->calculateProfit());

        // Verify order-level profit
        $this->assertEquals($expectedProfit, $order->calculateTotalProfit());
    }

    public function test_pos_sync_order_calculates_profit_correctly()
    {
        // Create a staff user for POS access
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        // Create a customer
        $customer = User::factory()->create();

        // Create a product with purchase price
        $product = Product::factory()->create([
            'name' => 'Sync Test Product',
            'price' => 150.00,
            'purchase_price' => 90.00,
            'current_stock' => 15,
        ]);

        // Act as staff user
        $this->actingAs($staff);

        // Sync offline POS orders
        $response = $this->postJson('/admin/api/pos/sync', [
            'orders' => [
                [
                    'user_id' => $customer->id,
                    'items' => [
                        [
                            'product_id' => $product->id,
                            'qty' => 1,
                            'price' => 150.00,
                        ]
                    ],
                    'payment_method' => 'card',
                    'subtotal' => 150.00,
                    'discount_total' => 0,
                    'tax_total' => 0,
                    'total_payable' => 150.00,
                    'created_at' => now()->subHour()->toDateTimeString(),
                ]
            ]
        ]);

        $response->assertStatus(200);
        $responseData = $response->json();

        // Verify sync was successful
        $this->assertTrue($responseData['success']);
        $this->assertEquals(1, $responseData['synced']);
        $this->assertEquals(0, $responseData['failed']);

        // Get the synced order
        $orderId = $responseData['synced_orders'][0]['order_id'];
        $order = Order::find($orderId);

        // Verify order exists and is POS order
        $this->assertNotNull($order);
        $this->assertEquals('pos', $order->source);
        $this->assertEquals($staff->id, $order->staff_id);

        // Verify order item has purchase price for profit calculation
        $orderItem = $order->items->first();
        $this->assertNotNull($orderItem);
        $this->assertEquals($product->purchase_price, $orderItem->purchase_price);

        // Verify profit calculation
        $expectedProfit = ($orderItem->price - $orderItem->purchase_price) * $orderItem->qty;
        $this->assertEquals($expectedProfit, $orderItem->calculateProfit());

        // Verify order-level profit
        $this->assertEquals($expectedProfit, $order->calculateTotalProfit());
    }

    public function test_pos_order_without_purchase_price_handles_gracefully()
    {
        // Create a staff user for POS access
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        // Create a customer
        $customer = User::factory()->create();

        // Create a product WITHOUT purchase price
        $product = Product::factory()->create([
            'name' => 'No Purchase Price Product',
            'price' => 200.00,
            'purchase_price' => null, // No purchase price set
            'current_stock' => 5,
        ]);

        // Act as staff user
        $this->actingAs($staff);

        // Create POS order
        $response = $this->postJson('/admin/api/pos/orders', [
            'user_id' => $customer->id,
            'items' => [
                [
                    'product_id' => $product->id,
                    'qty' => 1,
                    'price' => 200.00,
                ]
            ],
            'payment_method' => 'cash',
            'subtotal' => 200.00,
            'discount_total' => 0,
            'tax_total' => 0,
            'total_payable' => 200.00,
        ]);

        $response->assertStatus(201);
        $responseData = $response->json();

        // Verify order was created
        $this->assertTrue($responseData['success']);
        $orderId = $responseData['data']['order_id'];

        // Verify order exists
        $order = Order::find($orderId);
        $this->assertNotNull($order);

        // Verify order item has null purchase price
        $orderItem = $order->items->first();
        $this->assertNotNull($orderItem);
        $this->assertNull($orderItem->purchase_price);

        // Verify profit calculation returns 0 when no purchase price
        $this->assertEquals(0, $orderItem->calculateProfit());
        $this->assertEquals(0, $order->calculateTotalProfit());
    }
}