<?php

declare(strict_types=1);

namespace ApiModel\Action;

use ApiModel\Service\InventoryService;
use ApiModel\Service\InventoryAdjustmentService;
use ApiModel\Service\InventoryTransferService;
use ApiModel\Shared\Http\HttpUtil;
use ApiModel\Shared\Support\AuthContext;
use ApiModel\Shared\Support\CompanyContext;
use Psr\Http\Message\ServerRequestInterface;

final class InventoryAction
{
    public function __construct(
        private readonly InventoryService $inventory,
        private readonly InventoryAdjustmentService $adjustments,
        private readonly InventoryTransferService $transfers
    ) {}

    // --- Categories ---
    /** @return list<array<string, mixed>> */
    public function listCategories(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->inventory->listCategories($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getCategory(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        return $this->inventory->getCategory($id);
    }

    public function saveCategory(ServerRequestInterface $request, ?string $id = null): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);
        if ($id !== null) {
            $body['id'] = $id;
        }
        return $this->inventory->saveCategory($ctx['company_id'], $body);
    }

    public function deleteCategory(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $this->inventory->deleteCategory($id);
    }

    // --- Items ---
    /** @return list<array<string, mixed>> */
    public function listItems(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->inventory->listItems($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getItem(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->inventory->getItem($ctx['company_id'], $id);
    }

    public function saveItem(ServerRequestInterface $request, ?string $id = null): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);
        if ($id !== null) {
            $body['id'] = $id;
        }
        return $this->inventory->saveItem($ctx['company_id'], $body);
    }

    public function deleteItem(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->inventory->deleteItem($ctx['company_id'], $id);
    }

    // --- Warehouses ---
    /** @return list<array<string, mixed>> */
    public function listWarehouses(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->inventory->listWarehouses($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getWarehouse(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->inventory->getWarehouse($ctx['company_id'], $id);
    }

    public function saveWarehouse(ServerRequestInterface $request, ?string $id = null): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);
        if ($id !== null) {
            $body['id'] = $id;
        }
        return $this->inventory->saveWarehouse($ctx['company_id'], $body);
    }

    public function deleteWarehouse(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->inventory->deleteWarehouse($ctx['company_id'], $id);
    }

    /** @return list<array<string, mixed>> */
    public function getWarehouseStock(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        return $this->inventory->getWarehouseStock($id);
    }

    // --- Adjustments ---
    /** @return list<array<string, mixed>> */
    public function listAdjustments(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->adjustments->listAdjustments($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getAdjustment(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->adjustments->getAdjustment($ctx['company_id'], $id);
    }

    public function saveAdjustment(ServerRequestInterface $request, ?string $id = null): array
    {
        $user = AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);
        if ($id !== null) {
            $body['id'] = $id;
        }
        return $this->adjustments->saveAdjustment($ctx['company_id'], $ctx['branch_id'] ?? null, $user['userId'], $body);
    }

    public function deleteAdjustment(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->adjustments->deleteAdjustment($ctx['company_id'], $id);
    }

    // --- Transfers ---
    /** @return list<array<string, mixed>> */
    public function listTransfers(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->transfers->listTransfers($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getTransfer(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        return $this->transfers->getTransfer($ctx['company_id'], $id);
    }

    public function saveTransfer(ServerRequestInterface $request, ?string $id = null): array
    {
        $user = AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);
        if ($id !== null) {
            $body['id'] = $id;
        }
        return $this->transfers->saveTransfer($ctx['company_id'], $ctx['branch_id'] ?? null, $user['userId'], $body);
    }

    public function deleteTransfer(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->transfers->deleteTransfer($ctx['company_id'], $id);
    }
}
