<?php

namespace App\Http\Controllers;

use App\Http\Requests\CustomerOrderRequest;
use App\Models\Category;
use App\Models\Order;
use App\Models\Product;
use App\Models\Table;
use App\Models\User;
use App\Services\OrderService;
use Illuminate\Support\Facades\Cache;

class CustomerMenuController extends Controller
{
    public function __construct(private readonly OrderService $orderService) {}

    public function show(string $token)
    {
        $table = Table::query()
            ->where('qr_token', $token)
            ->where('is_active', true)
            ->with('outlet')
            ->firstOrFail();

        $outletId = (int) $table->outlet_id;

        $catalog = Cache::remember("pos.catalog.{$outletId}", 300, function () use ($outletId): array {
            return [
                'categories' => Category::query()
                    ->where('outlet_id', $outletId)
                    ->orderBy('sort_order')
                    ->get(),
                'products' => Product::query()
                    ->with(['variants.options', 'addons'])
                    ->where('outlet_id', $outletId)
                    ->where('is_active', true)
                    ->orderBy('name')
                    ->get(),
            ];
        });

        return view('customer.menu', [
            'table'      => $table,
            'outlet'     => $table->outlet,
            'categories' => $catalog['categories'],
            'products'   => $catalog['products'],
        ]);
    }

    public function store(CustomerOrderRequest $request, string $token)
    {
        $table = Table::query()
            ->where('qr_token', $token)
            ->where('is_active', true)
            ->firstOrFail();

        $outletId = (int) $table->outlet_id;

        $systemUser = User::query()
            ->where('outlet_id', $outletId)
            ->whereIn('role', ['owner', 'admin'])
            ->orderBy('id')
            ->first();

        abort_if(! $systemUser, 503, 'Outlet belum dikonfigurasi.');

        $validated = $request->validated();

        $payload = [
            'order_type'   => $validated['order_type'] ?? 'dine-in',
            'table_number' => $table->name,
            'discount'     => 0,
            'items'        => array_map(fn ($item) => [
                'product_id'        => $item['product_id'],
                'qty'               => $item['qty'],
                'note'              => $item['note'] ?? null,
                'variant_option_id' => $item['variant_option_id'] ?? null,
                'addon_ids'         => $item['addon_ids'] ?? [],
            ], $validated['items']),
            // Use PHP_INT_MAX so the service's payment validation passes; corrected after
            'payments' => [
                ['method' => 'QRIS', 'amount' => PHP_INT_MAX, 'reference' => 'SELF-ORDER'],
            ],
        ];

        $order = $this->orderService->createPaidOrder($payload, $systemUser->id, $outletId);

        $order->payments()->update(['amount' => $order->total]);
        $order->update(['source' => 'self_order']);

        $statusUrl = route('customer.order.status', ['token' => $token, 'order' => $order->id]);

        if ($request->expectsJson()) {
            return response()->json(['redirect' => $statusUrl]);
        }

        return redirect($statusUrl);
    }

    public function status(string $token, Order $order)
    {
        $table = Table::query()
            ->where('qr_token', $token)
            ->where('is_active', true)
            ->firstOrFail();

        abort_if($order->outlet_id !== (int) $table->outlet_id, 404);

        $order->load(['items', 'payments']);

        return view('customer.status', [
            'table' => $table,
            'order' => $order,
        ]);
    }
}
