<?php
/**
 * @author Daniel Knudsen <d.knudsen@spawntree.de>
 * @date 11.07.22
 */

require_once('Product.php');

class IsotopeDatabaseHandler
{
    const USER = 'root';
    const PASSWORD = '';
    const HOST = '127.0.0.1';
    const DB_NAME = 'wash_n_roll';

    private $dbHandle;

    public function __construct()
    {
        try {
            $this->dbHandle = new PDO('mysql:host='.self::HOST.';dbname='.self::DB_NAME.';charset=utf8',self::USER, self::PASSWORD);
            $this->dbHandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        } catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }


    public function processProducts(array $products)
    {
        $this->dbHandle->beginTransaction();

        $sql = "SELECT * FROM `tl_iso_product`";
        $stmt = $this->dbHandle->query($sql);
        $dbProducts = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $sql = "SELECT * FROM `tl_iso_product_price`";
        $stmt = $this->dbHandle->query($sql);
        $dbProductPrices = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $dbProductsBySku = [];
        foreach ($dbProducts as $prod) {
            $dbProductsBySku[$prod['sku']] = $prod;
        }

        $dbProductsPricesByPid = [];
        foreach ($dbProductPrices as $price) {
            $dbProductsPricesByPid[$price['pid']] = $price;
        }

        /** @var Product $product */
        foreach ($products as $product) {

            if (array_key_exists($product->getCode(), $dbProductsBySku)) {
                $dbProduct = $dbProductsBySku[$product->getCode()];
                $dbPrice = $dbProductsPricesByPid[$dbProduct['id']];
                $this->updateProduct($product, $dbProduct['id']);
                $this->updatePriceTier($product, $dbPrice['id']);

            } else {
                $productId = $this->createProduct($product);
                $productPriceId = $this->createPrice($product, $productId);
                $this->createPriceTier($product, $productPriceId);
            }
        }
        $this->dbHandle->commit();
    }

    private function updateProduct(Product $product, $productDbId)
    {
        $shippingWeight = $product->getGrossWeight() !== '' ?
            ($product->getNetWeight() !== '' ? $product->getNetWeight() : '') : '';

        $sql =
            "UPDATE `tl_iso_product` SET
                tstamp = ".time().",
                name = '".$product->getDescription()."',
                description = '".$product->getExtraDescription()."',
                shipping_weight = '$shippingWeight'
             WHERE `id` = ".$productDbId;
        $this->dbHandle->query($sql);
    }

    private function updatePriceTier(Product $product, $priceDbId)
    {
        $price = $product->getStandardSalesPrice() * (1 + Product::VAT);
        $sql =
            "UPDATE `tl_iso_product_pricetier` SET
                tstamp = ".time().",
                price = $price
             WHERE `pid` = ".$priceDbId;
        $this->dbHandle->query($sql);
    }

    private function createProduct(Product $product)
    {
        $alias = 'exact-product-'.$product->getCode();
        $shippingWeight = $product->getGrossWeight() !== '' ?
                        ($product->getNetWeight() !== '' ? $product->getNetWeight() : '') : '';
        $sql =
            "INSERT into `tl_iso_product` (
                pid,
                gid,
                tstamp,
                language,
                dateAdded,
                type,
                fallback,
                alias,
                gtin,
                sku,
                name,
                description,
                meta_title,
                baseprice,
                shipping_weight,
                shipping_exempt,
                shipping_pickup,
                shipping_price,
                protected,
                guests,
                cssID,
                published,
                start,
                stop
             ) VALUES (
                0,
                0,
                ".time().",
                '',
                ".time().",
                2,
                '',
                '$alias',
                '',
                '".$product->getCode()."',
                '".$product->getDescription()."',
                '".$product->getExtraDescription()."',
                '',
                '',
                '$shippingWeight',
                '',
                '',
                0.00,
                '',
                '',
                '',
                '0',
                '',
                ''
             )";
        $this->dbHandle->query($sql);
        return $this->dbHandle->lastInsertId();
    }

    private function createPrice(Product $product, $productDbId)
    {
        $sql =
            "INSERT INTO `tl_iso_product_price` (
                pid,
                tstamp,
                tax_class,
                config_id,
                member_group,
                start,
                stop
            ) VALUES (
                $productDbId,
                ".time().",
                1,
                0,
                0,
                '',
                ''
            )";
        $this->dbHandle->query($sql);
        return $this->dbHandle->lastInsertId();
    }

    private function createPriceTier(Product $product, $productPriceDbId)
    {
        $price = $product->getStandardSalesPrice() * (1 + Product::VAT);
        $sql =
            "INSERT INTO `tl_iso_product_pricetier` (
                pid,
                tstamp,
                min,
                price
            ) VALUES (
                $productPriceDbId,
                ".time().",
                1,
                $price
            )";
        $this->dbHandle->query($sql);
        return $this->dbHandle->lastInsertId();
    }
}