<?php

namespace App\Http\Controllers\Admin\Manage\Order;

use App\Enums\OrderChannel;
use App\Enums\OrderStatus;
use App\Enums\PaymentType;
use App\Http\Controllers\Concerns\FlashesEntityMessage;
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Manage\OrderRequest;
use App\Http\Requests\Admin\Manage\OrderStatusTransitionRequest;
use App\Models\Order;
use App\Services\Manage\OrderService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;

class OrderController extends Controller
{
    use FlashesEntityMessage, ParsesDataTableQuery;

    public function __construct(
        private readonly OrderService $orderService,
    ) {}

    public function index(Request $request): Response
    {
        $tableQuery = $this->parseDataTableQuery($request);

        return Inertia::render('admin/manage/orders/Index', [
            'orders' => $this->orderService->paginateForIndex($tableQuery, $request->user()),
            'filters' => $this->dataTableFilters($tableQuery),
        ]);
    }

    public function create(Request $request): Response
    {
        $user = $request->user();

        return Inertia::render('admin/manage/orders/Create', [
            'customers' => $this->orderService->customerOptions(),
            'marketings' => $this->orderService->marketingOptions(),
            'catalog' => $this->orderService->catalogItems(user: $user),
            'channels' => OrderChannel::selectOptions(),
            'storePriceTypes' => $this->orderService->storePriceTypeOptions(),
            'paymentTypes' => PaymentType::selectOptions(),
            'draftItems' => $this->orderService->draftItemsForUser($user),
        ]);
    }

    public function store(OrderRequest $request): RedirectResponse
    {
        $this->orderService->create($request->validated(), $request->user());

        $this->flashCreated('Pesanan');

        $params = [];

        if ($request->boolean('print')) {
            $params['print'] = 1;
            $params['paper_size'] = $request->input('paper_size', '80mm');
        }

        return redirect()->route('admin.manage.orders.index', $params);
    }

    public function show(Order $order): Response
    {
        return Inertia::render('admin/manage/orders/Show', [
            'order' => $this->orderService->findForShow($order),
        ]);
    }

    public function edit(Order $order): Response|RedirectResponse
    {
        try {
            $order->ensureEditable();
        } catch (ValidationException $exception) {
            $this->flashError($exception->validator->errors()->first('status'));

            return redirect()->route('admin.manage.orders.index');
        }

        return Inertia::render('admin/manage/orders/Edit', [
            'order' => $this->orderService->findForEdit($order),
            'customers' => $this->orderService->customerOptions(),
            'marketings' => $this->orderService->marketingOptions(),
            'catalog' => $this->orderService->catalogItems($order),
            'channels' => OrderChannel::selectOptions(),
            'storePriceTypes' => $this->orderService->storePriceTypeOptions(),
            'paymentTypes' => PaymentType::selectOptions(),
        ]);
    }

    public function update(OrderRequest $request, Order $order): RedirectResponse
    {
        $this->orderService->update($order, $request->validated());

        $this->flashUpdated('Pesanan');

        return redirect()->route('admin.manage.orders.index');
    }

    public function destroy(Order $order): RedirectResponse
    {
        $this->orderService->delete($order);

        $this->flashDeleted('Pesanan');

        return redirect()->route('admin.manage.orders.index');
    }

    public function transitionStatus(OrderStatusTransitionRequest $request, Order $order): RedirectResponse
    {
        $status = OrderStatus::from($request->validated('status'));

        $this->orderService->transitionStatus($order, $status);

        $this->flashSuccess($status->transitionStatusMessage());

        return redirect()->route('admin.manage.orders.index');
    }
}
