<?php

namespace Mnv\Modules\Shop;

use Mnv\Core\Utilities\Cookie\Session;

/**
 * Class Order
 * @package Mnv\Modules\Shop
 */
class Order
{
    /** @var string  */
    private string $shop_cart  = 'shop_cart';

    /** @var string  */
    private string $shop_orders  = 'shop_orders';

    /** @var string  */
    private string $shop_order_product  = 'shop_order_product';
    private string $shop_order_option  = 'shop_order_option';
    private string $shop_order_total  = 'shop_order_total';

    /** @var int */
    public $orderId;

    /** @var  */
    public $success;

    /** @var array */
    public $order;

    /** @var array  */
    public $response = [];

    /** @var array  */
    public $errors = [];


    /** Проверка корзины по токена для получение корзины по `token` */
    public function getOrder()
    {
        $data = [];
        if (!empty($this->orderId)) {
            $order_info = connect($this->shop_orders)->select('*')->where('order_id', $this->orderId)->get('array');
            if (!empty($order_info)) {
                $data['order_id']   = $this->orderId;
                $data['userId']         = $order_info['userId'];
                $data['fullName']       = $order_info['fullName'];
                $data['firstName']      = $order_info['firstName'];
                $data['lastName']       = $order_info['lastName'];
                $data['email']          = $order_info['email'];
                $data['phone']          = $order_info['phone'];
                $data['address']        = $order_info['address'];
                $data['createdBy']      = $order_info['createdBy'];
                $data['payment_choice'] = $order_info['payment_choice'];
                $data['payment_method'] = $order_info['payment_method'];
                $data['shipping_zone']  = $order_info['shipping_zone'];
                $data['shipping_date']  = $order_info['shipping_date'];
                $data['shipping_method']        = $order_info['shipping_method'];
                $data['shipping_coordinates']   = $order_info['shipping_coordinates'];
                $data['status']                 = $order_info['status'];
                $data['state']                  = $order_info['state'];
                $data['shipping_amount']        = $order_info['shipping_amount'];
                $data['products_amount']        = $order_info['products_amount'];
                $data['amount']                 = $order_info['amount'];
                $data['message']                = $order_info['message'];
//

                $products = $this->getOrderProducts($this->orderId);
                foreach ($products as $product) {
                    $data['products'][] = array(
                        'product_id' => $product['product_id'],
                        'name'       => $product['name'],
                        'sku'        => $product['sku'],
                        'ikpu'       => $product['ikpu'],
                        'url'        => connect('products')->select('url')->where('productId', $product['product_id'])->getValue(),
                        'option'     => $this->getOrderOptions($this->orderId, $product['order_product_id']),
                        'quantity'   => $product['quantity'],
                        'price'      => $product['price'],
                        'total'      => $product['total'],
                    );
                }

                $data['totals'] = $this->getOrderTotals($this->orderId);
            }
        }

//        print_r($data);

        return $data;
    }

    private function getOrderProducts($orderId): ?array
    {
        return connect($this->shop_order_product)->select('*')->where('order_id', $orderId)->getAll('array');
    }

    private function getOrderOptions($orderId, $order_product_id): ?array
    {
       return connect($this->shop_order_option)->select('*')->where('order_id', $orderId)->where('order_product_id', $order_product_id)->getAll('array');
    }

    private function getOrderTotals($orderId): ?array
    {
       return connect($this->shop_order_total)->select('*')->where('order_id', $orderId)->orderBy('sort_order')->getAll('array');
    }

    public function validate(array $order)
    {
        $products_amount = 0;
        $total_amount = 0;
        $order['shipping_amount'] = isset($order['shipping_amount']) ? str_replace(" ", "", $order['shipping_amount']) : 0.00;

        // сбор данных заказа и заказчика
        $order_data = [
            'userId'                => $order['userId'] ?? 0,
            'fullName'              => $order['fullName'],
            'email'                 => $order['email'] ?? null,
            'phone'                 => $order['phone'] ?? null,
            'address'               => $order['address'] ?? null,
            'message'               => $order['message'] ?? null,
            'createdBy'             => gmdate('Y-m-d H:i:s'),
            'payment_choice'        => $order['payment_choice'] ?? null,        // Способ оплаты
            'payment_method'        => $order['payment_method'],                // Метод оплаты
            'shipping_zone'         => $order['shipping_zone'] ?? null,         // Город доставки
            'shipping_date'         => $order['shipping_date'] ?? null,         // Дата и время доставки
            'shipping_coordinates'  => $order['shipping_coordinates'] ?? null,  // локация - координаты
            'shipping_amount'       => $order['shipping_amount'] ?? null,       // Метод доставки
        ];

        $order_data['products'] = [];
        // перебрать товар из корзины
        foreach ($this->getCartProducts() as $product) {
            $option_data = [];
            // Options product
            if (!empty($product['option'])) {
                foreach ($product['option'] as $option) {
                    $option_data[] = array(
                        'product_option_id'         => $option['product_option_id'],
                        'product_option_value_id'   => $option['product_option_value_id'],
                        'option_id'                 => $option['option_id'],
                        'option_value_id'           => $option['option_value_id'],
                        'name'                      => $option['name'],
                        'value'                     => $option['value'],
                        'type'                      => $option['type']
                    );
                }
            }

            // Products
            $order_data['products'][] = array(
                'product_id'    => $product['product_id'],
                'name'          => $product['title'],
                'brand'         => $product['brand'],
                'sku'           => $product['sku'],
                'ikpu'          => $product['ikpu'],
                'option'        => $option_data,
                'quantity'      => $product['quantity'],
                'subtract'      => $product['subtract'],
                'price'         => $product['price'],
                'total'         => $product['total'],
            );

            // подсчет общей суммы за товары
            $products_amount += $product['price'] * $product['quantity'];
        }

        $total_amount = $products_amount + $order['shipping_amount'];

        $order_data += [
            'products_amount'   => $products_amount,
            'amount'            => $total_amount,
        ];

        $order_data['totals'][] = $this->sub_total($products_amount);
        $order_data['totals'][] = $this->shipping($order['shipping_amount']);
        $order_data['totals'][] = $this->total_amount($total_amount);

//        print_r($order_data);
        $this->orderId = $this->addOrder($order_data);

        if (!empty($this->orderId)) {
            connect($this->shop_cart)->where('token', Session::get('token_cart_id'))->delete();
        }

        return $this->orderId;
    }

    public function addOrder($data)
    {
        $order_id = connect('shop_orders')->insert([
            'userId'                => $data['userId'],
            'fullName'              => $data['fullName'],
            'email'                 => $data['email'],
            'phone'                 => $data['phone'],
            'address'               => $data['address'],
            'message'               => $data['message'],
            'createdBy'             => gmdate('Y-m-d H:i:s'),
            'payment_choice'        => $data['payment_choice'] ?? null,
            'payment_method'        => $data['payment_method'] ?? null,
            'shipping_zone'         => $data['shipping_zone'] ?? null,
            'shipping_date'         => $data['shipping_date'] ?? null,
            'shipping_method'       => $data['shipping_method'] ?? null,
            'shipping_coordinates'  => $data['shipping_coordinates'] ?? null,
            'shipping_amount'       => $data['shipping_amount'] ?? 0.00,
            'products_amount'       => $data['products_amount'] ?? null,
            'amount'                => $data['amount'],
            'state'                 => 1,
            'order_status_id'       => 2,
            'status'                => 'waiting',
            'click_trans_id'        => 0,
            'click_paydoc_id'       => 0
        ]);

        // Products
        if (isset($data['products'])) {
            foreach ($data['products'] as $product) {
                $order_product_id = connect('shop_order_product')->insert([
                    'order_id'      => (int)$order_id,
                    'product_id'    => (int)$product['product_id'],
                    'name'          => $product['name'],
                    'brand'         => $product['brand'],
                    'sku'           => $product['sku'],
                    'ikpu'          => $product['ikpu'],
                    'quantity'      => (int)$product['quantity'],
                    'price'         => (int)$product['price'],
                    'total'         => (int)$product['total'],
                ]);

                if (!empty($product['option'])) {
                    foreach ($product['option'] as $option) {
                        connect('shop_order_option')->insert([
                            'order_id'                  => $order_id,
                            'order_product_id'          => $order_product_id,
                            'product_option_id'         => $option['product_option_id'],
                            'product_option_value_id'   => $option['product_option_value_id'],
                            'name'                      => $option['name'],
                            'value'                     => $option['value'],
                            'type'                      => $option['type'],
                        ]);
                    }
                }
            }
        }

        // Totals
        if (isset($data['totals'])) {
            foreach ($data['totals'] as $total) {
                connect('shop_order_total')->insert([
                    'order_id'      => (int)$order_id,
                    'code'          => $total['code'],
                    'title'         => $total['title'],
                    'value'         => $total['value'],
                    'sort_order'    => $total['sort_order'],
                ]);
            }
        }

        return $order_id;
    }

    // получить товара из корзины
    private function getCartProducts(): array
    {
        $product_data = [];
        $carts = connect('shop_cart')->where('token', Session::get('token_cart_id'))->getAll('array');

        foreach ($carts as $cart) {
            $stock = true;

            $product = connect('products')->select('productId, sectionId, title, brand, sku, ikpu, price, old_price, quantity, special, shipping, subtract')->where('productId', $cart['productId'])->get('array');
            if ($product && ($cart['quantity'] > 0)) {
                $product = prepareProduct($product);
//                $product['brand'] = connect('brands')->select('name')->where('fileName', $product['brand'])->getValue();
                $product['brand'] = connect('sections')->select('name')->where('sectionId', $product['sectionId'])->getValue();
                $option_price = 0;

                $option_data = array();

                foreach (json_decode($cart['options']) as $product_option_id => $value) {
                    $option_query = connect('product_option')->join('options', 'optionId', '=', 'option_id')->select('product_option_id, product_id, option_id, value, name, type, orderBy')->where('product_option_id', $product_option_id)->where('product_id', $product['productId'])->get('array');
                    if ($option_query) {
                        foreach ($value as $product_option_value_id) {
                            $option_value = connect('product_option_value')->join('options', 'optionId', '=', 'option_value_id')->select('option_value_id, name, hardware, quantity, subtract, price, price_prefix')->where('product_option_value_id', $product_option_value_id)->where('product_option_id', $product_option_id)->get('array');
                            if ($option_value) {
                                if ($option_value['price_prefix'] == '+') {
                                    $option_price += $option_value['price'];
                                } elseif ($option_value['price_prefix'] == '-') {
                                    $option_price -= $option_value['price'];
                                }

                                // Stock
                                if ($option_value['subtract'] && (!$option_value['quantity'] || ($option_value['quantity'] < $cart['quantity']))) {
                                    $stock = false;
                                }

                                $option_data[] = array(
                                    'product_option_id'       => $product_option_id,
                                    'product_option_value_id' => $product_option_value_id,
                                    'option_id'               => $option_query['option_id'],
                                    'option_value_id'         => $option_value['option_value_id'],
                                    'name'                    => $option_query['name'],
                                    'value'                   => $option_value['name'],
                                    'type'                    => $option_query['type'],

                                    'quantity'                => $option_value['quantity'],
                                    'subtract'                => $option_value['subtract'],
                                    'price'                   => $option_value['price'],
                                    'price_prefix'            => $option_value['price_prefix'],
                                );
                            }
                        }
                    }
                }

                $price = $product['price'];

                // Stock
                if (!$product['quantity'] || ($product['quantity'] < $cart['quantity'])) {
                    $stock = false;
                }

                $product_data[] = array(
                    'product_id'      => $product['productId'],
                    'title'           => $product['brand'] . ' ' . $product['title'],
                    'brand'           => $product['brand'],
                    'sku'             => $product['sku'],
                    'ikpu'            => $product['ikpu'],
                    'image'           => $product['image'],
                    'option'          => $option_data,
                    'quantity'        => $cart['quantity'],
                    'subtract'        => $product['subtract'],
                    'price'           => ($price + $option_price),
                    'total'           => ($price + $option_price) * $cart['quantity'],
                );
            }
        }

//        print_r($product_data);
        return $product_data;
    }



    /** предварительная сумма (сумма за товар) */
    private function sub_total($products_amount): array
    {
        return array(
            'code'       => 'sub_total',
            'title'      => 'Сумма',
            'value'      => $products_amount,
            'sort_order' => 1
        );
    }
    /** сумма за доставку */
    private function shipping($shipping_amount): array
    {
       return array(
            'code'       => 'shipping',
            'title'      => 'Стоимость доставки',
            'value'      => $shipping_amount,
            'sort_order' => 2
        );
    }

    /** итого к оплате */
    private function total_amount($total_amount): array
    {
        return array(
            'code'       => 'total',
            'title'      => 'Итого',
            'value'      => $total_amount,
            'sort_order' => 3
        );

    }


}