<?php

namespace Modules\Order\Services\Order;

use Darryldecode\Cart\Exceptions\InvalidConditionException;
use Darryldecode\Cart\Exceptions\InvalidItemException;
use Exception;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Collection;
use Modules\Order\Enums\OrderStatus;
use Modules\Order\Models\Order;
use Throwable;

interface OrderServiceInterface
{
    /**
     * Label for the resource.
     *
     * @return string
     */
    public function label(): string;

    /**
     * Model for the resource.
     *
     * @return string
     */
    public function model(): string;

    /**
     * Get a new instance of the model.
     *
     * @return Order
     */
    public function getModel(): Order;


    /**
     * Display a listing of the resource.
     *
     * @param array $filters
     * @param array $sorts
     * @return LengthAwarePaginator
     */
    public function get(array $filters = [], array $sorts = []): LengthAwarePaginator;

    /**
     * Show the specified resource.
     *
     * @param int|string $id
     * @return Order
     * @throws ModelNotFoundException
     */
    public function show(int|string $id): Order;

    /**
     * Get structure filters for frontend
     *
     * @return array
     */
    public function getStructureFilters(): array;

    /**
     * Cancel order
     *
     * @param int|string $id
     * @param array $data
     * @return void
     */
    public function cancel(int|string $id, array $data): void;

    /**
     * Refund order
     *
     * @param int|string $id
     * @param array $data
     * @return void
     */
    public function refund(int|string $id, array $data): void;

    /**
     * Get specific resource
     *
     * @param int|string $id
     * @param bool $withBranch
     * @return Order|Builder|EloquentCollection|array;
     * @throws ModelNotFoundException
     */
    public function findOrFail(int|string $id, bool $withBranch = false): Order|Builder|EloquentCollection|array;

    /**
     * Get update status meta
     *
     * @param int|string $id
     * @return array
     */
    public function getUpdateStatusMeta(int|string $id): array;

    /**
     * Get add payment meta
     *
     * @param int|string $id
     * @return array
     */
    public function getAddPaymentMeta(int|string $id): array;

    /**
     * Get active orders
     *
     * @return Collection
     */
    public function activeOrders(): Collection;

    /**
     * Get upcoming orders
     *
     * @return Collection
     */
    public function upcomingOrders(): Collection;

    /**
     * Get orders for a kitchen
     *
     * @return Collection
     */
    public function getOrdersForKitchen(): Collection;

    /**
     * Add payment
     *
     * @param int|string $id
     * @param array $data
     * @return void
     * @throws Throwable
     */
    public function addPayment(string|int $id, array $data): void;

    /**
     * Add payment merge
     *
     * @param int $mergeId
     * @param array $data
     * @return void
     * @throws Throwable
     */
    public function addPaymentMerge(int $mergeId, array $data): void;

    /**
     * Move to next status
     *
     * @param string|int $id
     * @return OrderStatus
     * @throws Throwable
     */
    public function moveToNextStatus(string|int $id): OrderStatus;

    /**
     * Kitchen move to next status
     *
     * @param string|int $id
     * @return OrderStatus
     * @throws Throwable
     */
    public function kitchenMoveToNextStatus(string|int $id): OrderStatus;

    /**
     * Get order for print data
     *
     * @param string|int $id
     * @return array
     */
    public function getPrintData(string|int $id): array;

    /**
     * Print order
     *
     * @param string|int $id
     * @param array|null $roles
     * @return void
     * @throws Exception
     */
    public function print(string|int $id, ?array $roles = null): void;

    /**
     * Get form edit meta
     *
     * @param int|string $id
     * @return array
     * @throws InvalidConditionException
     * @throws InvalidItemException
     */
    public function getFormEditMeta(int|string $id): array;
}
