<?php

namespace Tests\Feature;

use App\Models\Product;
use App\Models\User;
use App\Services\PriceService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class WholesalePriceTest extends TestCase
{
    use RefreshDatabase;

    protected PriceService $priceService;

    protected function setUp(): void
    {
        parent::setUp();
        $this->priceService = new PriceService();
    }

    /**
     * Test PriceService returns sale price for retail customer
     */
    public function test_price_service_returns_sale_price_for_retail_customer()
    {
        $product = Product::factory()->create([
            'price' => 100.00,
            'wholesale_price' => 80.00,
        ]);

        $retailCustomer = User::factory()->create([
            'customer_type' => 'retail',
        ]);

        $price = $this->priceService->getPriceForCustomer($product, $retailCustomer);

        $this->assertEquals(100.00, $price);
    }

    /**
     * Test PriceService returns wholesale price for wholesale customer
     */
    public function test_price_service_returns_wholesale_price_for_wholesale_customer()
    {
        $product = Product::factory()->create([
            'price' => 100.00,
            'wholesale_price' => 80.00,
        ]);

        $wholesaleCustomer = User::factory()->create([
            'customer_type' => 'wholesale',
        ]);

        $price = $this->priceService->getPriceForCustomer($product, $wholesaleCustomer);

        $this->assertEquals(80.00, $price);
    }

    /**
     * Test PriceService falls back to sale price when wholesale_price is null
     */
    public function test_price_service_falls_back_to_sale_price_when_wholesale_price_is_null()
    {
        $product = Product::factory()->create([
            'price' => 100.00,
            'wholesale_price' => null,
        ]);

        $wholesaleCustomer = User::factory()->create([
            'customer_type' => 'wholesale',
        ]);

        $price = $this->priceService->getPriceForCustomer($product, $wholesaleCustomer);

        $this->assertEquals(100.00, $price);
    }

    /**
     * Test PriceService returns sale price when customer is null
     */
    public function test_price_service_returns_sale_price_when_customer_is_null()
    {
        $product = Product::factory()->create([
            'price' => 100.00,
            'wholesale_price' => 80.00,
        ]);

        $price = $this->priceService->getPriceForCustomer($product, null);

        $this->assertEquals(100.00, $price);
    }

    /**
     * Test PriceService getPriceLabel returns correct label for retail customer
     */
    public function test_price_service_label_for_retail_customer()
    {
        $retailCustomer = User::factory()->create([
            'customer_type' => 'retail',
        ]);

        $label = $this->priceService->getPriceLabel($retailCustomer);

        $this->assertEquals('Sale Price', $label);
    }

    /**
     * Test PriceService getPriceLabel returns correct label for wholesale customer
     */
    public function test_price_service_label_for_wholesale_customer()
    {
        $wholesaleCustomer = User::factory()->create([
            'customer_type' => 'wholesale',
        ]);

        $label = $this->priceService->getPriceLabel($wholesaleCustomer);

        $this->assertEquals('Wholesale Price', $label);
    }

    /**
     * Test POS Product API returns correct prices for retail customer
     */
    public function test_pos_product_api_returns_correct_prices_for_retail_customer()
    {
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        $retailCustomer = User::factory()->create([
            'customer_type' => 'retail',
        ]);

        $product = Product::factory()->create([
            'price' => 100.00,
            'wholesale_price' => 80.00,
            'current_stock' => 10,
            'is_active' => true,
        ]);

        $this->actingAs($staff);

        $response = $this->getJson("/admin/api/pos/products?customer_id={$retailCustomer->id}");

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'data' => [
                    '*' => [
                        'id',
                        'name',
                        'price',
                        'sale_price',
                        'wholesale_price',
                        'effective_price',
                        'price_type',
                    ],
                ],
            ]);

        $productData = collect($response->json('data'))->firstWhere('id', $product->id);
        
        $this->assertNotNull($productData);
        $this->assertEquals(100.00, $productData['sale_price']);
        $this->assertEquals(80.00, $productData['wholesale_price']);
        $this->assertEquals(100.00, $productData['effective_price']);
        $this->assertEquals('retail', $productData['price_type']);
    }

    /**
     * Test POS Product API returns correct prices for wholesale customer
     */
    public function test_pos_product_api_returns_correct_prices_for_wholesale_customer()
    {
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        $wholesaleCustomer = User::factory()->create([
            'customer_type' => 'wholesale',
        ]);

        $product = Product::factory()->create([
            'price' => 100.00,
            'wholesale_price' => 80.00,
            'current_stock' => 10,
            'is_active' => true,
        ]);

        $this->actingAs($staff);

        $response = $this->getJson("/admin/api/pos/products?customer_id={$wholesaleCustomer->id}");

        $response->assertStatus(200);

        $productData = collect($response->json('data'))->firstWhere('id', $product->id);
        
        $this->assertNotNull($productData);
        $this->assertEquals(100.00, $productData['sale_price']);
        $this->assertEquals(80.00, $productData['wholesale_price']);
        $this->assertEquals(80.00, $productData['effective_price']);
        $this->assertEquals('wholesale', $productData['price_type']);
    }

    /**
     * Test POS Product API falls back to sale price when wholesale_price is null
     */
    public function test_pos_product_api_falls_back_to_sale_price_when_wholesale_price_is_null()
    {
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        $wholesaleCustomer = User::factory()->create([
            'customer_type' => 'wholesale',
        ]);

        $product = Product::factory()->create([
            'price' => 100.00,
            'wholesale_price' => null,
            'current_stock' => 10,
            'is_active' => true,
        ]);

        $this->actingAs($staff);

        $response = $this->getJson("/admin/api/pos/products?customer_id={$wholesaleCustomer->id}");

        $response->assertStatus(200);

        $productData = collect($response->json('data'))->firstWhere('id', $product->id);
        
        $this->assertNotNull($productData);
        $this->assertEquals(100.00, $productData['effective_price']);
        $this->assertEquals('wholesale', $productData['price_type']);
    }

    /**
     * Test POS Customer API includes customer_type in response
     */
    public function test_pos_customer_api_includes_customer_type()
    {
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        $wholesaleCustomer = User::factory()->create([
            'customer_type' => 'wholesale',
            'mobile' => '9876543210',
        ]);

        $this->actingAs($staff);

        $response = $this->getJson("/admin/api/pos/customers/search?mobile=9876");

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'data' => [
                    '*' => [
                        'id',
                        'name',
                        'mobile',
                        'email',
                        'customer_type',
                    ],
                ],
            ]);

        $customerData = collect($response->json('data'))->firstWhere('id', $wholesaleCustomer->id);
        
        $this->assertNotNull($customerData);
        $this->assertEquals('wholesale', $customerData['customer_type']);
    }

    /**
     * Test POS Customer creation with customer_type
     */
    public function test_pos_customer_creation_with_customer_type()
    {
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        $this->actingAs($staff);

        $response = $this->postJson('/admin/api/pos/customers', [
            'name' => 'Test Wholesale Customer',
            'mobile' => '9876543210',
            'email' => 'wholesale@test.com',
            'customer_type' => 'wholesale',
        ]);

        $response->assertStatus(201)
            ->assertJsonStructure([
                'success',
                'data' => [
                    'id',
                    'name',
                    'mobile',
                    'email',
                    'customer_type',
                ],
            ]);

        $this->assertEquals('wholesale', $response->json('data.customer_type'));

        // Verify customer was created in database
        $customer = User::where('mobile', '9876543210')->first();
        $this->assertNotNull($customer);
        $this->assertEquals('wholesale', $customer->customer_type);
    }

    /**
     * Test POS Customer creation defaults to retail when customer_type not provided
     */
    public function test_pos_customer_creation_defaults_to_retail()
    {
        $staff = User::factory()->create();
        $staff->assignRole('staff');

        $this->actingAs($staff);

        $response = $this->postJson('/admin/api/pos/customers', [
            'name' => 'Test Retail Customer',
            'mobile' => '9876543211',
            'email' => 'retail@test.com',
        ]);

        $response->assertStatus(201);

        $this->assertEquals('retail', $response->json('data.customer_type'));

        // Verify customer was created in database
        $customer = User::where('mobile', '9876543211')->first();
        $this->assertNotNull($customer);
        $this->assertEquals('retail', $customer->customer_type);
    }
}

