<?php

namespace Tests\Feature\Api;

use App\Models\Category;
use App\Models\Order;
use App\Models\Payment;
use App\Models\Product;

class OrderManagementTest extends ApiTestCase
{
    protected Category $category;
    protected Product $product;

    protected function setUp(): void
    {
        parent::setUp();
        $this->createAuthenticatedUser();

        $this->category = Category::create(['name' => 'Ice Cream', 'slug' => 'ice-cream', 'is_active' => true]);
        $this->product = Product::create([
            'name' => 'Vanilla Scoop',
            'slug' => 'vanilla-scoop',
            'category_id' => $this->category->id,
            'base_price' => 5.00,
            'is_active' => true,
        ]);
    }

    // ==================== ORDER TESTS ====================

    public function test_can_list_orders(): void
    {
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-001',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 10.00,
            'total_amount' => 10.00,
        ]);

        $response = $this->getJson('/api/v1/orders');

        $this->assertSuccessResponse($response);
        $this->assertCount(1, $response->json('data'));
    }

    public function test_can_create_order(): void
    {
        $response = $this->postJson('/api/v1/orders', [
            'branch_id' => $this->branch->id,
            'order_type' => Order::TYPE_DINE_IN,
            'customer_name' => 'John Doe',
            'notes' => 'Extra napkins',
            'items' => [
                [
                    'product_id' => $this->product->id,
                    'product_name' => $this->product->name,
                    'quantity' => 2,
                    'unit_price' => 5.00,
                    'total_price' => 10.00,
                ],
            ],
        ]);

        $this->assertSuccessResponse($response, 201);
        $this->assertDatabaseHas('orders', [
            'branch_id' => $this->branch->id,
            'customer_name' => 'John Doe',
        ]);
    }

    public function test_can_show_order(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-002',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $response = $this->getJson("/api/v1/orders/{$order->id}");

        $this->assertSuccessResponse($response);
        $response->assertJson(['data' => ['order_number' => 'ORD-002']]);
    }

    public function test_can_update_order(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-003',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $response = $this->putJson("/api/v1/orders/{$order->id}", [
            'customer_name' => 'Jane Doe',
            'notes' => 'Updated notes',
        ]);

        $this->assertSuccessResponse($response);
        $this->assertDatabaseHas('orders', ['id' => $order->id, 'customer_name' => 'Jane Doe']);
    }

    public function test_can_update_order_status(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-004',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $response = $this->putJson("/api/v1/orders/{$order->id}/status", [
            'status' => Order::STATUS_PREPARING,
        ]);

        $this->assertSuccessResponse($response);
        $this->assertDatabaseHas('orders', ['id' => $order->id, 'status' => Order::STATUS_PREPARING]);
    }

    public function test_can_cancel_order(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-005',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $response = $this->postJson("/api/v1/orders/{$order->id}/cancel", [
            'reason' => 'Customer request',
        ]);

        $this->assertSuccessResponse($response);
        $this->assertDatabaseHas('orders', ['id' => $order->id, 'status' => Order::STATUS_CANCELLED]);
    }

    public function test_can_apply_discount(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-006',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 100.00,
            'total_amount' => 100.00,
        ]);

        // Add items so calculateTotals works correctly
        $order->items()->create([
            'product_id' => $this->product->id,
            'product_name' => $this->product->name,
            'quantity' => 20,
            'unit_price' => 5.00,
            'total_price' => 100.00,
        ]);

        $response = $this->postJson("/api/v1/orders/{$order->id}/discount", [
            'amount' => 10.00,
            'reason' => 'Customer discount',
        ]);

        $this->assertSuccessResponse($response);
        $order->refresh();
        $this->assertEquals(10.00, $order->discount_amount);
        $this->assertEquals(90.00, $order->total_amount);
    }

    public function test_can_list_orders_by_branch(): void
    {
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-007',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $response = $this->getJson("/api/v1/orders/branch/{$this->branch->id}");

        $this->assertSuccessResponse($response);
        $this->assertCount(1, $response->json('data'));
    }

    public function test_can_list_active_orders_for_branch(): void
    {
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-008',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-009',
            'status' => Order::STATUS_COMPLETED,
            'subtotal' => 20.00,
            'total_amount' => 20.00,
        ]);

        $response = $this->getJson("/api/v1/orders/branch/{$this->branch->id}/active");

        $this->assertSuccessResponse($response);
        $this->assertCount(1, $response->json('data'));
    }

    public function test_can_list_today_orders(): void
    {
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-010',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $response = $this->getJson("/api/v1/orders/branch/{$this->branch->id}/today");

        $this->assertSuccessResponse($response);
    }

    public function test_can_get_daily_summary(): void
    {
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-011',
            'status' => Order::STATUS_COMPLETED,
            'subtotal' => 100.00,
            'total_amount' => 100.00,
        ]);

        $response = $this->getJson("/api/v1/orders/branch/{$this->branch->id}/daily-summary");

        $this->assertSuccessResponse($response);
    }

    // ==================== PAYMENT TESTS ====================

    public function test_can_add_payment_to_order(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-012',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 50.00,
            'total_amount' => 50.00,
        ]);

        $response = $this->postJson("/api/v1/orders/{$order->id}/payments", [
            'method' => 'cash',
            'amount' => 50.00,
        ]);

        $this->assertSuccessResponse($response, 201);
        $this->assertDatabaseHas('payments', [
            'order_id' => $order->id,
            'method' => 'cash',
            'amount' => 50.00,
        ]);
    }

    public function test_can_list_order_payments(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-013',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 50.00,
            'total_amount' => 50.00,
        ]);
        Payment::create([
            'order_id' => $order->id,
            'user_id' => $this->user->id,
            'method' => 'cash',
            'amount' => 50.00,
            'status' => 'completed',
        ]);

        $response = $this->getJson("/api/v1/orders/{$order->id}/payments");

        $this->assertSuccessResponse($response);
        $this->assertCount(1, $response->json('data'));
    }

    public function test_can_refund_payment(): void
    {
        $order = Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-014',
            'status' => Order::STATUS_COMPLETED,
            'subtotal' => 50.00,
            'total_amount' => 50.00,
        ]);
        $payment = Payment::create([
            'order_id' => $order->id,
            'user_id' => $this->user->id,
            'method' => 'cash',
            'amount' => 50.00,
            'status' => 'completed',
        ]);

        $response = $this->postJson("/api/v1/orders/{$order->id}/payments/{$payment->id}/refund", [
            'amount' => 50.00,
            'reason' => 'Customer requested refund',
        ]);

        $this->assertSuccessResponse($response);
    }

    public function test_can_list_orders_by_status(): void
    {
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-015',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $response = $this->getJson("/api/v1/orders/branch/{$this->branch->id}/status/pending");

        $this->assertSuccessResponse($response);
    }

    public function test_can_list_orders_by_date_range(): void
    {
        Order::create([
            'branch_id' => $this->branch->id,
            'user_id' => $this->user->id,
            'order_number' => 'ORD-016',
            'status' => Order::STATUS_PENDING,
            'subtotal' => 15.00,
            'total_amount' => 15.00,
        ]);

        $startDate = now()->subDays(7)->toDateString();
        $endDate = now()->toDateString();

        $response = $this->getJson("/api/v1/orders/branch/{$this->branch->id}/date-range?start_date={$startDate}&end_date={$endDate}");

        $this->assertSuccessResponse($response);
    }
}
