<?php

use App\Models\Branch;
use App\Models\Category;
use App\Models\Item;
use App\Models\Kot;
use App\Models\KotItem;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\RestaurantTable;
use App\Models\TableArea;
use App\Models\User;

use function Pest\Laravel\getJson;
use function Pest\Laravel\postJson;

beforeEach(function () {
    // Set up database environment manually to guarantee valid foreign constraint references
    $this->owner = User::factory()->create([
        'role' => 'owner',
    ]);

    $this->branch = Branch::create([
        'user_id' => $this->owner->id,
        'name' => 'Main Street Branch',
        'slug' => 'main-street-branch',
        'address' => '123 Main St',
        'phone' => '1234567890',
        'active' => true,
    ]);

    $this->biller = User::factory()->create([
        'role' => 'biller',
        'active_branch_id' => $this->branch->id,
        'parent_id' => $this->owner->id,
        'active' => 1,
    ]);

    $this->token = $this->biller->createToken('test-token')->plainTextToken;

    // Create an area
    $this->area = TableArea::create([
        'branch_id' => $this->branch->id,
        'name' => 'Main Hall',
        'is_active' => true,
    ]);
});

test('table endpoints require authentication', function () {
    getJson(url('api/biller/tables'))->assertStatus(401);
    postJson(url('api/biller/tables/layout'), ['tables' => []])->assertStatus(401);
});

test('biller can load restaurant tables and floor plan', function () {
    $table = RestaurantTable::create([
        'branch_id' => $this->branch->id,
        'area_id' => $this->area->id,
        'name' => 'Table 01',
        'capacity' => 4,
        'status' => 'occupied',
        'pos_x' => 120,
        'pos_y' => 80,
        'width' => 60,
        'height' => 60,
        'shape' => 'square',
        'is_active' => true,
    ]);

    $response = getJson(
        url('api/biller/tables'),
        ['Authorization' => "Bearer $this->token"]
    );

    $response->assertStatus(200)
        ->assertJsonCount(1)
        ->assertJsonFragment([
            'id' => $table->id,
            'area_id' => $this->area->id,
            'name' => 'Table 01',
            'capacity' => 4,
            'status' => 'occupied',
            'pos_x' => 120,
            'pos_y' => 80,
            'width' => 60,
            'height' => 60,
            'shape' => 'square',
            'has_ready_items' => false,
            'active_order' => null,
        ]);
});

test('biller can load restaurant tables with active orders and ready items status', function () {
    $table = RestaurantTable::create([
        'branch_id' => $this->branch->id,
        'area_id' => $this->area->id,
        'name' => 'Table 01',
        'capacity' => 4,
        'status' => 'occupied',
        'pos_x' => 120,
        'pos_y' => 80,
        'width' => 60,
        'height' => 60,
        'shape' => 'square',
        'is_active' => true,
    ]);

    // Create an order
    $order = Order::create([
        'branch_id' => $this->branch->id,
        'table_id' => $table->id,
        'status' => 'active',
        'grand_total' => 34.50,
    ]);

    // Create item category and item
    $category = Category::create([
        'branch_id' => $this->branch->id,
        'name' => 'Burgers',
        'slug' => 'burgers',
        'is_active' => true,
    ]);

    $item = Item::create([
        'branch_id' => $this->branch->id,
        'category_id' => $category->id,
        'name' => 'Chicken Burger',
        'slug' => 'chicken-burger',
        'price' => 12.50,
        'dine_in_price' => 12.50,
        'delivery_price' => 14.00,
        'takeaway_price' => 12.50,
        'gst_percentage' => 5.00,
        'tax_inclusive' => true,
        'available_dine_in' => true,
        'available_delivery' => true,
        'available_takeaway' => true,
        'is_active' => true,
    ]);

    // Create OrderItem
    $orderItem = OrderItem::create([
        'order_id' => $order->id,
        'item_id' => $item->id,
        'name' => 'Chicken Burger',
        'price' => 12.50,
        'quantity' => 2,
        'subtotal' => 25.00,
    ]);

    // Create KOT and KOT Item
    $kot = Kot::create([
        'branch_id' => $this->branch->id,
        'order_id' => $order->id,
        'status' => 'ready',
    ]);

    KotItem::create([
        'kot_id' => $kot->id,
        'order_item_id' => $orderItem->id,
        'quantity' => 2,
        'status' => 'ready',
    ]);

    $response = getJson(
        url('api/biller/tables'),
        ['Authorization' => "Bearer $this->token"]
    );

    $response->assertStatus(200)
        ->assertJsonFragment([
            'id' => $table->id,
            'has_ready_items' => true,
        ])
        ->assertJsonPath('0.active_order.id', $order->id)
        ->assertJsonPath('0.active_order.grand_total', '34.50')
        ->assertJsonPath('0.active_order.items.0.id', $orderItem->id)
        ->assertJsonPath('0.active_order.items.0.name', 'Chicken Burger')
        ->assertJsonPath('0.active_order.items.0.price', '12.50')
        ->assertJsonPath('0.active_order.items.0.quantity', 2);
});

test('biller can update floor map coordinates', function () {
    $table1 = RestaurantTable::create([
        'branch_id' => $this->branch->id,
        'area_id' => $this->area->id,
        'name' => 'Table 01',
        'capacity' => 4,
        'status' => 'available',
        'pos_x' => 120,
        'pos_y' => 80,
        'width' => 60,
        'height' => 60,
        'shape' => 'square',
        'is_active' => true,
    ]);

    $table2 = RestaurantTable::create([
        'branch_id' => $this->branch->id,
        'area_id' => $this->area->id,
        'name' => 'Table 02',
        'capacity' => 4,
        'status' => 'available',
        'pos_x' => 200,
        'pos_y' => 100,
        'width' => 60,
        'height' => 60,
        'shape' => 'square',
        'is_active' => true,
    ]);

    $payload = [
        'tables' => [
            ['id' => $table1->id, 'pos_x' => 150, 'pos_y' => 95],
            ['id' => $table2->id, 'pos_x' => 250, 'pos_y' => 150],
        ],
    ];

    $response = postJson(
        url('api/biller/tables/layout'),
        $payload,
        ['Authorization' => "Bearer $this->token"]
    );

    $response->assertStatus(200)
        ->assertJson(['success' => true]);

    $this->assertDatabaseHas('restaurant_tables', [
        'id' => $table1->id,
        'pos_x' => 150,
        'pos_y' => 95,
    ]);

    $this->assertDatabaseHas('restaurant_tables', [
        'id' => $table2->id,
        'pos_x' => 250,
        'pos_y' => 150,
    ]);
});
