<?php

namespace Tests\Feature;

use App\Models\Brand;
use App\Models\Cart;
use App\Models\Category;
use App\Models\PageContent;
use App\Models\PaymentMethod;
use App\Models\Product;
use App\Models\ShippingMethod;
use App\Models\Unit;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ECommerceApiTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Test public API endpoints for listing catalog master data.
     */
    public function test_public_catalog_endpoints(): void
    {
        Category::factory()->create(['name' => 'Bedding', 'slug' => 'bedding', 'code' => 'bedding']);
        Product::create([
            'name' => 'Monica Pillow',
            'price' => 15.00,
            'category' => 'bedding',
            'in_stock' => true,
        ]);
        Brand::create(['name' => 'Monica', 'slug' => 'monica', 'is_active' => true]);
        Unit::create(['name' => 'Piece', 'abbreviation' => 'pcs', 'is_active' => true]);

        // Products
        $this->getJson('/api/v1/products')->assertOk()
            ->assertJsonStructure(['data'])
            ->assertJsonPath('data.0.name', 'Monica Pillow');

        // Categories
        $this->getJson('/api/v1/categories')->assertOk()
            ->assertJsonStructure(['data'])
            ->assertJsonPath('data.0.name', 'Bedding');

        // Brands
        $this->getJson('/api/v1/brands')->assertOk()
            ->assertJsonStructure(['success', 'data'])
            ->assertJsonPath('data.0.name', 'Monica');

        // Units
        $this->getJson('/api/v1/units')->assertOk()
            ->assertJsonStructure(['success', 'data'])
            ->assertJsonPath('data.0.name', 'Piece');
    }

    /**
     * Test customer authentication.
     */
    public function test_customer_authentication_flow(): void
    {
        // 1. Register
        $response = $this->postJson('/api/v1/auth/register', [
            'name' => 'Customer User',
            'email' => 'customer@example.com',
            'password' => 'password123',
            'password_confirmation' => 'password123',
        ]);
        $response->assertStatus(201)->assertJsonStructure(['token', 'user']);

        // 2. Login
        $response = $this->postJson('/api/v1/auth/login', [
            'email' => 'customer@example.com',
            'password' => 'password123',
        ]);
        $response->assertOk()->assertJsonStructure(['token', 'user']);
        $token = $response->json('token');

        // 3. Protected user route
        $this->withToken($token)->getJson('/api/v1/auth/user')
            ->assertOk()
            ->assertJsonPath('email', 'customer@example.com');

        // 4. Logout
        $this->withToken($token)->postJson('/api/v1/auth/logout')->assertOk();
    }

    /**
     * Test shopping cart APIs.
     */
    public function test_shopping_cart_apis(): void
    {
        $user = User::factory()->create();
        $token = auth('api')->login($user);
        $product = Product::create([
            'name' => 'Monica Pillow',
            'price' => 15.00,
            'category' => 'bedding',
            'in_stock' => true,
        ]);

        // Add to cart
        $this->withToken($token)->postJson('/api/v1/auth/cart', [
            'product_id' => $product->id,
            'quantity' => 2,
        ])->assertOk();

        $this->assertDatabaseHas('carts', [
            'user_id' => $user->id,
            'product_id' => $product->id,
            'quantity' => 2,
        ]);

        // List cart items
        $this->withToken($token)->getJson('/api/v1/auth/cart')->assertOk()
            ->assertJsonStructure(['data'])
            ->assertJsonPath('data.0.pivot.quantity', 2);

        // Delete item
        $this->withToken($token)->deleteJson("/api/v1/auth/cart/{$product->id}")->assertOk();
        $this->assertDatabaseMissing('carts', [
            'user_id' => $user->id,
            'product_id' => $product->id,
        ]);
    }

    /**
     * Test checkout and order placement.
     */
    public function test_checkout_and_order_placement(): void
    {
        $user = User::factory()->create();
        $token = auth('api')->login($user);
        
        $product = Product::create([
            'name' => 'Monica Bed Sheets',
            'price' => 50.00,
            'category' => 'bedding',
            'in_stock' => true,
        ]);

        // Add to cart
        Cart::create([
            'user_id' => $user->id,
            'product_id' => $product->id,
            'quantity' => 1,
        ]);

        $shippingMethod = ShippingMethod::create([
            'name' => 'Standard Delivery',
            'code' => 'delivery',
            'fixed_fee' => 2.00,
            'is_active' => true,
        ]);

        // Checkout order
        $response = $this->withToken($token)->postJson('/api/v1/auth/orders', [
            'items' => [
                ['product_id' => $product->id, 'quantity' => 1],
            ],
            'shipping_method_id' => $shippingMethod->id,
            'shipping_detail' => 'https://maps.google.com/?q=11.55,104.91',
            'customer_name' => 'Test Customer',
            'customer_phone' => '012345678',
            'customer_email' => 'test@example.com',
            'payment_method' => 'cod',
            'discount' => 5.00,
        ]);

        $response->assertStatus(201);
        
        // Verify Order in database
        $this->assertDatabaseHas('orders', [
            'user_id' => $user->id,
            'subtotal' => 50.00,
            'discount' => 5.00,
            'shipping_fee' => 2.00,
            'total' => 47.00, // 50 - 5 + 2 = 47
            'shipping_method_id' => $shippingMethod->id,
            'shipping_method_name' => $shippingMethod->name,
            'shipping_method_code' => $shippingMethod->code,
        ]);

        // Cart should be cleared
        $this->assertDatabaseMissing('carts', [
            'user_id' => $user->id,
        ]);

        // Checkout order without shipping_detail (optional)
        $responseWithoutShippingDetail = $this->withToken($token)->postJson('/api/v1/auth/orders', [
            'items' => [
                ['product_id' => $product->id, 'quantity' => 1],
            ],
            'shipping_method_id' => $shippingMethod->id,
            'customer_name' => 'No Address Customer',
            'customer_phone' => '0987654321',
            'customer_email' => 'noaddress@example.com',
            'payment_method' => 'cod',
        ]);
        $responseWithoutShippingDetail->assertStatus(201);
    }

    /**
     * Test CMS settings APIs.
     */
    public function test_cms_settings_api(): void
    {
        PageContent::create(['section' => 'home', 'title_en' => 'Welcome Home']);
        
        $this->getJson('/api/v1/pages/homepage')->assertOk()
            ->assertJsonPath('data.home.title', 'Welcome Home');
    }
}
