<?php

declare(strict_types=1);

namespace ApiModel\Action;

use ApiModel\Service\BillService;
use ApiModel\Service\PurchasePaymentService;
use ApiModel\Service\ExpenseService;
use ApiModel\Service\PurchaseOrderService;
use ApiModel\Shared\Http\HttpUtil;
use ApiModel\Shared\Support\AuthContext;
use ApiModel\Shared\Support\CompanyContext;
use Psr\Http\Message\ServerRequestInterface;

final class PurchasesAction
{
    public function __construct(
        private readonly BillService $bills,
        private readonly PurchasePaymentService $payments,
        private readonly ExpenseService $expenses,
        private readonly PurchaseOrderService $orders
    ) {}

    /** @return list<array<string, mixed>> */
    public function listOrders(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->orders->listOrders($ctx['company_id'], $ctx['branch_id'] ?? null);
    }

    /** @return array<string, mixed> */
    public function getOrder(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->orders->getOrder($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function saveOrder(ServerRequestInterface $request): array
    {
        $user = AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);

        return $this->orders->saveOrder($ctx['company_id'], $ctx['branch_id'] ?? null, $user['userId'], $body);
    }

    /** @return void */
    public function deleteOrder(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->orders->deleteOrder($ctx['company_id'], $id);
    }

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

    /** @return list<array<string, mixed>> */
    public function listBills(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->bills->listBills($ctx['company_id'], $ctx['branch_id'] ?? null);
    }

    /** @return array<string, mixed> */
    public function getBill(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->bills->getBill($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function saveBill(ServerRequestInterface $request): array
    {
        $user = AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);

        return $this->bills->saveBill($ctx['company_id'], $ctx['branch_id'] ?? null, $user['userId'], $body);
    }

    /** @return array{ok: true} */
    public function deleteBill(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->bills->deleteBill($ctx['company_id'], $id);
    }

    /** @return list<array<string, mixed>> */
    public function listUnpaidBills(ServerRequestInterface $request, string $vendorId): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->bills->listUnpaidByVendor($ctx['company_id'], $vendorId);
    }

    /** @return list<array<string, mixed>> */
    public function listPayments(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->payments->listPayments($ctx['company_id'], $ctx['branch_id'] ?? null);
    }

    /** @return array<string, mixed> */
    public function getPayment(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->payments->getPayment($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function savePayment(ServerRequestInterface $request): array
    {
        $user = AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);

        return $this->payments->savePayment($ctx['company_id'], $ctx['branch_id'] ?? null, $user['userId'], $body);
    }

    /** @return array{ok: true} */
    public function deletePayment(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->payments->deletePayment($ctx['company_id'], $id);
    }

    /** @return list<array<string, mixed>> */
    public function listExpenses(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->expenses->listExpenses($ctx['company_id'], $ctx['branch_id'] ?? null);
    }

    /** @return array<string, mixed> */
    public function getExpense(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->expenses->getExpense($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function saveExpense(ServerRequestInterface $request): array
    {
        $user = AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $body = HttpUtil::parseJson($request);

        return $this->expenses->saveExpense($ctx['company_id'], $ctx['branch_id'] ?? null, $user['userId'], $body);
    }

    /** @return array{ok: true} */
    public function deleteExpense(ServerRequestInterface $request, string $id): void
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->expenses->deleteExpense($ctx['company_id'], $id);
    }
}
