<?php

use App\Models\Branch;
use App\Models\Order;
use App\Models\RestaurantTable;
use App\Models\TableArea;
use App\Models\User;

use function Pest\Laravel\getJson;

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('dashboard endpoint requires authentication', function () {
    getJson(url('api/biller/dashboard'))->assertStatus(401);
});

test('biller can fetch dashboard metrics and trends with correct statistics', function () {
    $today = now();
    $yesterday = now()->subDay();

    // 1. Create yesterday's settled orders
    $orderYesterday = Order::create([
        'branch_id' => $this->branch->id,
        'biller_id' => $this->biller->id,
        'order_type' => 'dine_in',
        'status' => 'settled',
        'subtotal' => 2000.00,
        'gst_amount' => 0.00,
        'grand_total' => 2000.00,
    ]);
    $orderYesterday->created_at = $yesterday;
    $orderYesterday->save();

    // 2. Create today's settled orders
    $orderToday1 = Order::create([
        'branch_id' => $this->branch->id,
        'biller_id' => $this->biller->id,
        'order_type' => 'dine_in',
        'status' => 'settled',
        'subtotal' => 3000.00,
        'gst_amount' => 0.00,
        'grand_total' => 3000.00,
    ]);
    $orderToday1->created_at = $today;
    $orderToday1->save();

    $orderToday2 = Order::create([
        'branch_id' => $this->branch->id,
        'biller_id' => $this->biller->id,
        'order_type' => 'dine_in',
        'status' => 'settled',
        'subtotal' => 1053.00,
        'gst_amount' => 0.00,
        'grand_total' => 1053.00,
    ]);
    $orderToday2->created_at = $today;
    $orderToday2->save();

    // 3. Create active orders today
    $orderActive1 = Order::create([
        'branch_id' => $this->branch->id,
        'order_type' => 'dine_in',
        'status' => 'active',
        'subtotal' => 100.00,
        'gst_amount' => 0.00,
        'grand_total' => 100.00,
    ]);
    $orderActive1->created_at = $today;
    $orderActive1->save();

    $orderActive2 = Order::create([
        'branch_id' => $this->branch->id,
        'order_type' => 'dine_in',
        'status' => 'active',
        'subtotal' => 150.00,
        'gst_amount' => 0.00,
        'grand_total' => 150.00,
    ]);
    $orderActive2->created_at = $today;
    $orderActive2->save();

    // 4. Occupied tables
    RestaurantTable::create([
        'branch_id' => $this->branch->id,
        'area_id' => $this->area->id,
        'name' => 'Table 1',
        'status' => 'occupied',
        'capacity' => 4,
        'is_active' => true,
    ]);

    RestaurantTable::create([
        'branch_id' => $this->branch->id,
        'area_id' => $this->area->id,
        'name' => 'Table 2',
        'status' => 'available',
        'capacity' => 4,
        'is_active' => true,
    ]);

    // 5. Create an order and table in another branch to ensure multi-outlet isolation
    $otherBranch = Branch::create([
        'user_id' => $this->owner->id,
        'name' => 'Other Branch',
        'slug' => 'other-branch',
        'address' => '456 Other St',
        'phone' => '0987654321',
        'active' => true,
    ]);

    $otherArea = TableArea::create([
        'branch_id' => $otherBranch->id,
        'name' => 'Other Hall',
        'is_active' => true,
    ]);

    $orderOther = Order::create([
        'branch_id' => $otherBranch->id,
        'order_type' => 'dine_in',
        'status' => 'settled',
        'subtotal' => 5000.00,
        'gst_amount' => 0.00,
        'grand_total' => 5000.00,
    ]);
    $orderOther->created_at = $today;
    $orderOther->save();

    RestaurantTable::create([
        'branch_id' => $otherBranch->id,
        'area_id' => $otherArea->id,
        'name' => 'Table 3',
        'status' => 'occupied',
        'capacity' => 4,
        'is_active' => true,
    ]);

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

    // Verify response status and exact properties
    $response->assertSuccessful()
        ->assertJsonStructure([
            'today_sales',
            'yesterday_sales',
            'sales_change_percentage',
            'sales_change_formatted',
            'active_orders',
            'total_orders_today',
            'occupied_tables',
            'hourly_sales' => [
                '*' => ['hour', 'sales']
            ]
        ])
        ->assertJsonPath('today_sales', 4053)
        ->assertJsonPath('yesterday_sales', 2000)
        ->assertJsonPath('sales_change_percentage', 102.65)
        ->assertJsonPath('sales_change_formatted', '+102.65% vs yest.')
        ->assertJsonPath('active_orders', 2)
        ->assertJsonPath('total_orders_today', 4) // 2 active + 2 settled today
        ->assertJsonPath('occupied_tables', 1);

    // Verify hourly sales has exactly 24 hours
    $data = $response->json();
    expect($data['hourly_sales'])->toHaveCount(24);
});
