<?php

namespace Modules\Cart;

use Darryldecode\Cart\Exceptions\InvalidConditionException;
use Darryldecode\Cart\Exceptions\InvalidItemException;
use Modules\Order\Enums\OrderProductAction;
use Modules\Order\Enums\OrderProductStatus;
use Modules\Order\Models\Order;

class EditOrderCart extends Cart
{
    /**
     * Init edit order
     *
     * @param Order $order
     * @return void
     * @throws InvalidConditionException
     * @throws InvalidItemException
     */
    public function initEditOrder(Order $order): void
    {
        $this->clear();
        $this->addCurrentOrder($order);
        $this->addOrderType($order->type);

        foreach ($order->products as $product) {
            $options = [];
            foreach ($product->options as $option) {
                $options[$option->option_id] = $option->option->type->isFieldType()
                    ? $option->value
                    : $option->values->pluck('id')->toArray();

            }

            if (!in_array($product->status, [OrderProductStatus::Cancelled, OrderProductStatus::Refunded])) {
                $this->store($product->product->id, $product->quantity, $options, $product, $product->gift);
            }
        }

        if (!is_null($order->customer)) {
            $this->addCustomer($order->customer);
        }

        if ($order->hasDiscount()) {
            $this->applyDiscount($order->discount->discountable, $order->discount->gift);
        }
    }


    /**
     * Store/overwrite an action on a cart item (idempotent).
     *
     * @param string $id Cart line id (the cart item's unique id)
     * @param string $action Action key, e.g. "extra_spicy"
     * @param int $quantity Action quantity (>= 0)
     * @return void
     */
    public function storeAction(string $id, string $action, int $quantity): void
    {
        $item = $this->get($id);
        $actions = $item->attributes->actions ?? [];
        $status = [];

        switch ($action) {
            case OrderProductAction::Cancel->value:
                $status[] = OrderProductStatus::Preparing;
                break;
            case OrderProductAction::Refund->value:
                $status = [OrderProductStatus::Ready, OrderProductStatus::Served];
                break;
            default:
                return;
        }

        if (in_array($item->attributes->order_product['status'], $status) && $quantity <= $item->quantity) {

            $actions[$action] = [
                'id' => $action,
                'quantity' => $quantity + (isset($actions[$action]) ? $actions[$action]['quantity'] : 0)
            ];

            $this->update($id, [
                'attributes' => [...$item->attributes, "actions" => $actions],
                'quantity' => [
                    'relative' => false,
                    'value' => $item->quantity - $quantity,
                ],
            ]);
        }
    }

    /**
     * Delete action
     *
     * @param string $id Cart line id (the cart item's unique id)
     * @param string $action Action key, e.g. "extra_spicy"
     * @return void
     */
    public function deleteAction(string $id, string $action): void
    {
        $item = $this->get($id);
        $actions = $item->attributes->actions ?? [];
        $quantity = 0;

        if (isset($actions[$action])) {
            $quantity = $actions[$action]['quantity'];
            unset($actions[$action]);
        }

        $this->update($id, [
            'attributes' => [...$item->attributes, "actions" => $actions],
            'quantity' => [
                'relative' => false,
                'value' => $item->quantity + $quantity,
            ],
        ]);
    }
}
