<?php

class Orders
{
    public $ID = 0;
    public $path = ['to_root' => ''];
    public $right;
    public $orderValues;
    public $found = false;

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function __construct($id_order, $right = 'admin')
    {
        $this->ID = $id_order;
        $this->right = $right;
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function getOrder($print_header = false, $loadDataOnly = false)
    {
        global $dbcfg;

        $query['where'] = '';
        if ($this->right == 'user') {
            $query['where'] = "AND id_user='".$GLOBALS['ctrl']['id']."' ";
        }

        $SQL = sqlQuery("SELECT 
			DATE_FORMAT(date_created, '{$dbcfg->date_format}' ) AS date_c,
			DATE_FORMAT(COALESCE(date_accept, NOW()), '{$dbcfg->date_format}' ) AS date_a,
			DATE_FORMAT(COALESCE(date_handle, NOW()), '{$dbcfg->date_format}' ) AS date_h,
			DATE_FORMAT(COALESCE(date_handle, NOW()) + INTERVAL {$dbcfg->shop_due_days} DAY, '{$dbcfg->date_format}' ) AS date_s,
			COALESCE(date_handle, date_accept, NOW()) AS date_s_raw,
			id_user, order_no, total_price,
			status, status_payed, status_dispatch, status_storno, 
			invoice_name, invoice_surname, invoice_firm, 
			invoice_ico, invoice_dic, invoice_street, 
			invoice_city, invoice_zip, invoice_country, 
			invoice_phone, invoice_email, 
			delivery_name, delivery_surname, delivery_firm, 
			delivery_street, delivery_city, delivery_zip, delivery_country, 
			delivery_type, delivery_complete, 
			note_user, user_order_no
		FROM ".getTableName('orders')." 
		WHERE id='".$this->ID."' ".$query['where'].'
		LIMIT 1');
        $Found = sqlNumRows($SQL);
        if ($Found == 0) {
            $this->found = false;

            return false;
        } else {
            $this->found = true;
        }

        $this->orderValues = sqlFetchArray($SQL);

        if ($loadDataOnly == false) {
            return $this->printOrder($this->orderValues, $print_header, getVal('template', null, 'orderViewprint.tpl'));
        }
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function getOrderValues()
    {
        return $this->orderValues;
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function getFound()
    {
        return $this->found;
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function printOrder($order, $print_header = false, $template = 'orderViewprint.tpl')
    {
        $orderObj = new Order();
        $orderObj->createFromDB($this->ID);
        $orderObj->fetchItems();

        $setRecap = getVal('recap', null, false);

        if ($setRecap === '1') {
            $orderObj->status = false;
        } else {
            if ($setRecap === '0' && !$orderObj->status) {
                $orderObj->status = true;
            }
        }

        changeCurrency($orderObj->currency);

        $invoice_force = getVal('invoice_force');
        if (!empty($invoice_force)) {
            $orderObj->status = $invoice_force;
        }
        $classSmarty = createSmarty(false, true);

        $classSmarty->assign('header', ['show' => $print_header]);
        $classSmarty->assign('order', $orderObj);
        $html = $classSmarty->fetch('sharedtpl:'.$template);

        unset($classSmarty);
        changeCurrency();

        return $html;
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function recalculate($updateDB = true)
    {
        $totalPrice = toDecimal('0');

        // polozky faktury
        $SQLItems = sqlQuery('SELECT id_product, pieces, piece_price, total_price, descr, tax 
								FROM '.getTableName('order_items')." 
								WHERE id_order='".$this->ID."' 
								ORDER BY id ASC");

        foreach ($SQLItems as $row) {
            $Price = $row['total_price'];
            $vat = $row['tax'];

            $totalPrice = $totalPrice->add(calcPrice($Price, $vat));
        }

        // die((string)$totalPrice);

        // upravit v databazi
        if ($updateDB) {
            $SQL = sqlQuery('UPDATE '.getTableName('orders')." 
						SET total_price='".$totalPrice."' 
						WHERE id='".$this->ID."' ");
        }

        return $totalPrice;
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static function createOrderNumber($id, $pattern = null)
    {
        global $cfg;

        if (!$pattern) {
            $pattern = $cfg['Order']['number']['pattern'];
        }
        $orderNo = '';

        $offset = null;
        preg_match_all('/\[([^\[\]]*)\]/', $pattern, $matches);
        $no = count($matches[1]);

        for ($i = 0; $i < $no; $i++) {
            $fill = [
                'bool' => false,
            ];
            $orderNoPart = '';

            $param = null;
            if (strpos($matches[1][$i], ',') !== false) {
                list($typ, $param) = explode(',', $matches[1][$i]);
            } else {
                $typ = $matches[1][$i];
            }

            $Idcalc = preg_match('/#ID(\+|\-)(\d+)/i', $typ, $offset);
            if ($Idcalc || $typ == '#ID' || $typ == '#USER_ID' || $typ == '#USER_ORDER_INDEX' || $typ == '#IDID') {
                switch ($typ) {
                    case '#USER_ID':
                        $id_user = returnSQLResult('SELECT id_user FROM orders WHERE id=:id_order', ['id_order' => $id]);

                        $string = $id_user;

                        break;
                    case '#USER_ORDER_INDEX':
                        $id_user = returnSQLResult('SELECT id_user FROM orders WHERE id=:id_order', ['id_order' => $id]);
                        $index = returnSQLResult(
                            'SELECT MAX(CAST(order_no AS UNSIGNED)) FROM orders WHERE id_user=:id_user AND id != :id_order AND YEAR(date_created) = :this_year ',
                            ['id_user' => $id_user, 'id_order' => $id, 'this_year' => date('Y')]
                        );
                        $index = intval(substr($index, 4 + strlen((string) $id_user))) + 1;
                        $string = $index;

                        break;
                    default:
                        if ($Idcalc) {
                            $id = (string) ($id + intval($offset[1].$offset[2]));
                        }
                        $string = $id;

                        break;
                }

                $orderNoPart = $string;

                // pridani hodnoty
                if ($param != '') {
                    $fill['bool'] = true;
                    $fill['string'] = '0';
                    $fill['length'] = intval($param);
                    $fill['direction'] = 'begin'; // v jakem smeru doplnovat
                }
            } elseif (preg_match('/^"([^"]*)"$/i', $typ, $str)) {
                $orderNoPart = $str[1];

                // pridani hodnoty
                if ($param != '') {
                    $fill['bool'] = true;
                    $fill['string'] = $str[1];
                    $fill['length'] = intval($param);
                    $fill['direction'] = 'end'; // v jakem smeru doplnovat
                }
            } elseif // typ datum rok, mesic, den, tyden v roce
            ($typ == 'Y' || $typ == 'M' || $typ == 'D' || $typ == 'W'
                || $typ == 'H' || $typ == 'm' || $typ == 's'
            ) {
                switch ($typ) {
                    case 'Y':
                        $string = date('Y');
                        break;
                    case 'M':
                        $string = date('m');
                        break;
                    case 'D':
                        $string = date('d');
                        break;
                    case 'W':
                        $string = date('W');
                        break;
                    case 'H':
                        $string = date('H');
                        break;
                    case 'm':
                        $string = date('i');
                        break;
                    case 's':
                        $string = date('s');
                        break;
                }

                $orderNoPart = $string;

                // pridani hodnoty
                if ($param != '') {
                    $fill['bool'] = true;
                    $fill['string'] = $string;
                    $fill['length'] = intval($param);
                    $fill['direction'] = 'begin'; // v jakem smeru doplnovat
                }
            } elseif // typ nahodne cislo
            ($typ == '*'
            ) {
                $length = (intval($param) > 0) ? intval($param) : 1;

                for ($x = 0; $x < $length; $x++) {
                    $orderNoPart .= (string) rand(0, 9);
                }

                unset($length);
            } elseif ($typ === '#RANDOM') {
                foreach (range(1, $param ?: 6) as $_) {
                    $orderNoPart .= mt_rand(empty($orderNoPart) ? 1 : 0, 9);
                }
            } elseif // typ cislo doplnit nulami na zacatek
            (is_numeric($typ)) {
                $orderNoPart = $typ;

                // pridani hodnoty
                if ($param != '') {
                    $fill['bool'] = true;
                    $fill['string'] = '0';
                    $fill['length'] = intval($param);
                    $fill['direction'] = 'begin'; // v jakem smeru doplnovat
                }
            }

            // kdyz se ma retezec doplnit na urcit delku
            if ($fill['bool'] && $fill['string'] != '' && $fill['length'] > 0) {
                while (strlen($orderNoPart) < $fill['length']) {
                    switch ($fill['direction']) {
                        case 'begin':
                            $orderNoPart = $fill['string'].$orderNoPart;
                            break;
                        case 'end':
                            $orderNoPart .= $fill['string'];
                            break;
                        default:
                            $orderNoPart = $fill['string'].$orderNoPart;
                    }
                }

                // oriznuti prebytku
                if ($typ != '#ID') {
                    switch ($fill['direction']) {
                        case 'begin':
                            if (strlen($orderNoPart) > $fill['length']) {
                                $orderNoPart = substr($orderNoPart, ceil(strlen($orderNoPart) - $fill['length']), strlen($orderNoPart));
                            }
                            break;
                        case 'end':
                            $orderNoPart = substr($orderNoPart, 0, $fill['length']);
                            break;
                        default:
                            if (strlen($orderNoPart) > $fill['length']) {
                                $orderNoPart = substr($orderNoPart, ceil(strlen($orderNoPart) - $fill['length']), strlen($orderNoPart));
                            }
                    }
                }
            }

            // doplnit do celkoveho cisla obj.
            $orderNo .= $orderNoPart;
        }

        return $orderNo;

        // ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
