<?php

use KupShop\CatalogBundle\Section\SectionFinder;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;

class Import_XMLfeed extends Window
{
    use DatabaseCommunication;

    public $listProducer;
    protected $template = 'window/import.xml_feed.tpl';

    public function handle()
    {
        if (getVal('Submit') && isset($_REQUEST['type']) && $_REQUEST['type'] == 'xmlFeed') {
            global $cfg;
            $noErrors = 0;
            $type = 'XML Feed';
            $listVAT = [];
            $listLabel = [];

            $query = sqlQuery('SELECT id, vat FROM '.getTableName('vats'));
            while ($row = sqlFetchArray($query)) {
                $listVAT[$row['id']] = $row['vat'];
            }

            $query = sqlQuery('SELECT id, name FROM '.getTableName('producers'));
            while ($row = sqlFetchArray($query)) {
                $this->listProducer[$row['id']] = strtolower($row['name']);
            }

            $query = sqlQuery('SELECT id, label FROM '.getTableName('products_variations_choices_labels'));
            while ($row = sqlFetchArray($query)) {
                $listLabel[$row['id']] = $row['label'];
            }

            $xml = simplexml_load_file($_REQUEST['feedUrl']);

            if ($xml === false) {
                $ErrStr = 'Chyba stahovani XML souboru.';
                redirect('launch.php?s=board.php&type=import&what='.$type.'&ErrStr='.urlencode($ErrStr));
            }

            if (!empty($_FILES['xsltFile']['size'])) {
                // die(print_r($_FILES['xsltFile']));
                $xslt = new XSLTProcessor();
                $xslt->importStylesheet(simplexml_load_file($_FILES['xsltFile']['tmp_name']));
                $xml = simplexml_load_string($xslt->transformToXml($xml));
                if ($xml === false) {
                    $ErrStr = 'Chyba aplikovani XSLT transformace';
                    redirect('launch.php?s=board.php&type=import&what='.$type.'&ErrStr='.urlencode($ErrStr));
                }
            }

            $sectionFinder = ServiceContainer::getService(SectionFinder::class);

            sqlStartTransaction();

            if ($_REQUEST['dbSave'] == 'delete_and_insert_new') {
                sqlQuery('TRUNCATE '.getTableName('products'));
                sqlQuery('TRUNCATE '.$cfg['DbTable']['photos-products']);
                sqlQuery('TRUNCATE '.getTableName('photos'));
            }

            clearCache('categories-menu');

            $category_separator = '/';
            $codes = [];
            $imageCache = [];

            foreach ($xml->SHOPITEM as $item) {
                if (!empty($item->PRODUCT)) {
                    $title = $item->PRODUCT;
                } elseif (!empty($item->PRODUCTNAME)) {
                    $title = $item->PRODUCTNAME;
                }

                // Get Code
                $code = null;
                if (!empty($item->CODE)) {
                    $code = strval($item->CODE);
                } elseif (!empty($item->PRODUCTNO)) {
                    $code = strval($item->PRODUCTNO);
                } elseif (!empty($item->ITEM_ID)) {
                    $code = strval($item->ITEM_ID);
                } elseif (!empty($_REQUEST['codePattern'])) {
                    if (preg_match("@{$_REQUEST['codePattern']}@", $item->URL, $matches) >= 1) {
                        $code = $matches[1];
                    } else {
                        echo "Error matching '{$item->URL}' to '{$_REQUEST['codePattern']}'";
                    }
                }

                if (empty($code)) {
                    exit("Empty code for product '{$title}'".print_r($item, true));
                }

                if (isset($codes[$code])) {
                    continue;
                }

                $codes[$code] = true;

                if (!empty($item->SHORT_DESCRIPTION)) {
                    $short_descr = strval($item->SHORT_DESCRIPTION->asXML());
                }

                if (!empty($item->EAN)) {
                    $ean = strval($item->EAN);
                }

                if (!empty($item->DESCRIPTION)) {
                    $long_descr = strval($item->DESCRIPTION->children()->asXML());
                }
                if (empty($long_descr)) {
                    unset($long_descr);
                }

                // Get Prices
                $price = floatval(strtr($item->PRICE, ',', '.'));
                $price_vat = floatval(strtr($item->PRICE_VAT, ',', '.'));

                if (!empty($item->VAT)) {
                    $vat = floatval(strtr($item->VAT, ',', '.')) * 100;
                } elseif (!empty($price) && !empty($price_vat)) {
                    $vat = round((($price_vat / $price) - 1) * 100);
                } else {
                    $vat = $listVAT[1];
                } // Fall-back to default VAT

                if (empty($price) && !empty($price_vat)) {
                    $price = $price_vat / (1 + $vat / 100.);
                }

                if (!empty($item->DISCOUNT)) {
                    $price_common = $price * (1 + $vat / 100.);
                    $price = $price * (1 - floatval(strtr($item->DISCOUNT, ',', '.')));
                }

                $vat = $this->findVAT($vat, $listVAT);

                // Get Others
                if (!empty($item->PRODUCER)) {
                    $producer = $this->findProducer($item->PRODUCER);
                } elseif (!empty($item->MANUFACTURER)) {
                    $producer = $this->findProducer($item->MANUFACTURER);
                }
                $in_store = intval($item->IN_STORE);
                $delivery_time = round($item->AVAILABILITY / 24);
                if ($delivery_time <= 0) {
                    $delivery_time = -1;
                }

                // Get Category
                $category = '';
                if (!empty($item->CATEGORYTEXT)) {
                    $category .= strval($item->CATEGORYTEXT);
                } elseif (!empty($item->CATEGORY)) {
                    $category .= strval($item->CATEGORY);
                }

                // Check if already exists
                $product_id = null;
                if ($_REQUEST['dbSave'] == 'update') {
                    $product_id = returnSQLResult('SELECT id FROM '.getTableName('products')." WHERE code='".sqlFormatInput($code)."'");
                }

                $exists = $product_id > 0;
                $updateFields = ['title', 'code', 'ean', 'short_descr', 'long_descr', 'price', 'price_common', 'vat', 'producer', 'in_store', 'delivery_time', 'discount'];

                $fields = [];
                foreach ($updateFields as $key) {
                    if (isset($$key)) {
                        $fields[$key] = $$key;
                    }
                }

                // Insert into DB
                if (!$exists) {
                    if (!$this->insertSQL('products', $fields)) {// sqlQuery("INSERT INTO ".getTableName("products")." SET $fields"))
                        $noErrors++;
                    }
                    $product_id = sqlInsertId();
                } elseif (!$this->updateSQL('products', $fields, ['id' => $product_id])) {// sqlQuery("UPDATE ".getTableName("products")." SET $fields WHERE id=$product_id"))
                    $noErrors++;
                }

                // Insert category into DB
                if (!$exists && !empty($category)) {
                    static $separator_guesed = false;
                    if (!$separator_guesed) {
                        if (substr_count($category, '|') > substr_count($category, '/')) {
                            $category_separator = '|';
                        }
                        $separator_guesed = true;
                    }

                    $parts = explode($category_separator, $category);
                    $category = $sectionFinder->findSection($parts);

                    sqlQuery('INSERT INTO '.getTableName('products_in_sections')."
                  (id_product, id_section) VALUES
                  ({$product_id}, {$category})
                  ON DUPLICATE KEY UPDATE id_product=id_product");
                }

                // Download images
                $imagesCount = returnSQLResult('SELECT COUNT(*) FROM '.getTableName('photos_products_relation')." WHERE id_product='{$product_id}'");
                if ((!$exists || $imagesCount == 0) && getVal('downloadImages') == 'yes') {
                    $filename = $cfg['Path']['photos'].'import.jpg';

                    $images = [];

                    // Temporary hack - get image from detail url
                    /*
                    if(!empty($item->URL) && !isset($imageCache[strval($item->IMGURL)]))
                    {
                       $content = file_get_contents(strval($item->URL));
                       if (preg_match("@http://obchod.pumpa.cz/images/sklady/[^\']+@", $content, $matches))
                          $images[] = $matches[0];
                       elseif (preg_match("@/images/sklady/[^\"']+@", $content, $matches))
                          $images[] = "http://eshop.cerpadlavrchlabi.cz".$matches[0];
                    }
                    */

                    if (empty($images)) {
                        $images = [];
                        if (!empty($item->IMGURL)) {
                            $images[] = strval($item->IMGURL);
                        }

                        if (!empty($item->IMAGES)) {
                            foreach ($item->IMAGES->IMGURL as $image) {
                                $images[] = strval($image);
                            }
                        }
                    }

                    $first = true;
                    foreach ($images as $imageUrl) {
                        if (isset($imageCache[$imageUrl])) {
                            $photo_id = $imageCache[$imageUrl];
                        } else {
                            if (!$this->stream_copy($imageUrl, $filename)) {
                                continue;
                            }

                            $path_parts = pathinfo($imageUrl);

                            if (empty($path_parts['extension'])) {
                                $path_parts['basename'] .= '.jpg';
                                $path_parts['extension'] = 'jpg';
                            }
                            $_FILES['picture']['name'] = $path_parts['basename'];
                            $_FILES['picture']['type'] = strtolower($path_parts['extension']);
                            $_FILES['picture']['tmp_name'] = $filename;
                            $img = new Photos('product');
                            $img->newImage();
                            $img->uploadImage($_FILES['picture'], false);

                            // ulozit do Databaze
                            $img->insertImageIntoDB($path_parts['basename'], '', '');
                            $photo_id = $img->getID();
                            $imageCache[$imageUrl] = $photo_id;
                        }

                        if (!sqlQuery('INSERT INTO '.$cfg['DbTable']['photos-products']." (id_photo, id_product, show_in_lead, active) VALUES ({$photo_id}, {$product_id}, '".($first ? 'Y' : 'N')."', 'Y')")) {
                            $noErrors++;
                        }
                        $first = false;
                    }
                }

                // Import variants
                if (!empty($item->VARIATIONS)) {
                    $product = new Product($product_id);

                    foreach ($item->VARIATIONS->VARIATION as $variation) {
                        $labels = [];
                        foreach ($variation->LABEL as $label) {
                            $labels[$this->findLabel(strval($label['name']), $listLabel)] = strval($label);
                        }

                        $variation_id = \Variations::createProductVariation($product_id, $labels);

                        $in_store = ($variation->AVAILABILITY != 0) ? 1 : 0;
                        $title = $variation->TITLE;

                        $fields = ['in_store' => $in_store, 'title' => $title]; // queryCreate(array("in_store", "title"));

                        $this->updateSQL('products_variations', $fields, ['id' => $variation_id]);
                        // sqlQuery("UPDATE ".getTableName("products_variations")." SET $fields WHERE id=$variation_id");
                    }

                    $product->updateInStore();
                    $product->updateDeliveryTime();
                }
                /*
                            if(!empty($item->VARIANT))
                            {
                               $product = new Product($product_id);

                               foreach ($item->VARIANT as $variation)
                               {
                                  $parts = preg_split("/ - /", strval($variation->PRODUCTNAME));
                                  if (count($parts) != 3)
                                  {
                                     echo "Error parsing variation: '{$title}'";
                                     continue;
                                  }
                                  $partLabels = explode("||", $parts[1]);
                                  $partValues = explode("||", $parts[2]);
                                  $labels = array();
                                  foreach($partLabels as $index => $label)
                                     $labels[$this->findLabel(strval($label), $listLabel)] = strval($partValues[$index]);

                                  $variation_id = $product->createVariation($labels);

                                  $price = $variation->PRICE_VAT / ((100 + $vat) / 100);

                                  //$fields = queryCreate(array("price"));

                                  $fields = ["price" => $price];

                                  $this->updateSQL("products_variations", $fields, ["id" => $variation_id]);

                                  //sqlQuery("UPDATE ".getTableName("products_variations")." SET $fields WHERE id=$variation_id");
                               }

                               $product->updateInStore();
                               $product->updateDeliveryTime();
                            }
                */
                foreach ($updateFields as $field) {
                    unset($$field);
                }
            }

            // if($_REQUEST['downloadImages'] == "yes")
            //   if (isset($filename))
            //      unlink($filename);

            clearCache('categories-menu');

            sqlFinishTransaction();

            if ($noErrors == 0) {
                $ErrStr = 'Import proběhl úspěšně.';
                redirect('launch.php?s=import.xml_feed.php&ErrStr='.urlencode($ErrStr));
            } else {
                $ErrStr = 'Vyskytly se chyby při importu. Počet chyb: '.(string) $noErrors;
                redirect('launch.php?s=import.xml_feed.php&ErrStr='.urlencode($ErrStr));
            }
        }
    }

    public function findVAT($percent, $listVAT)
    {
        if ($index = array_search($percent, $listVAT)) {
            return $index;
        }

        sqlQuery('INSERT INTO '.getTableName('vats')." (descr, vat) VALUES ('Daň {$percent}%', {$percent})");
        $index = sqlInsertId();

        $listVAT[$index] = $percent;

        return $index;
    }

    public function findProducer($name)
    {
        $name = trim($name);
        if ($name == '') {
            return 0;
        }

        if (($index = array_search(strtolower($name), $this->listProducer)) !== false) {
            return $index;
        }

        $this->insertSQL('producers', ['name' => $name]);
        $index = sqlInsertId();

        $this->listProducer[$index] = strtolower($name);

        return $index;
    }

    public function findLabel($name, $listLabel)
    {
        if ($name == '') {
            return 0;
        }

        if (($index = array_search($name, $listLabel)) !== false) {
            return $index;
        }

        sqlQuery('INSERT INTO '.getTableName('products_variations_choices_labels')." (label) VALUES ('{$name}')");
        $index = sqlInsertId();

        $listLabel[$index] = $name;

        return $index;
    }

    public function stream_copy($src, $dest)
    {
        $fsrc = fopen($src, 'r');

        if (!$fsrc) {
            return 0;
        }

        $fdest = fopen($dest, 'w+');
        $len = stream_copy_to_stream($fsrc, $fdest);
        fclose($fsrc);
        fclose($fdest);

        return $len;
    }
}

$importxmlfeed = new Import_XMLfeed();
$importxmlfeed->run();
