<?php

declare(strict_types=1);

namespace KupShop\WatchdogBundle\Resources\upgrade;

use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Functional\Mapping;

class WatchdogUpgrade extends \UpgradeNew
{
    public function check_PriceColumn(): bool
    {
        return $this->checkColumnExists('products_watchdog', 'price');
    }

    /** Add products_watchdog.price column */
    public function upgrade_PriceColumn(): void
    {
        sqlQuery('ALTER TABLE products_watchdog ADD COLUMN availability TINYINT DEFAULT 1 AFTER last_in_store');
        sqlQuery('ALTER TABLE products_watchdog ADD COLUMN price DECIMAL(15,4) DEFAULT NULL AFTER last_in_store');

        $this->upgradeOK();
    }

    public function check_SiteColumn(): bool
    {
        return $this->checkColumnExists('products_watchdog', 'id_site');
    }

    /** watchdog: add `id_site` and `currency` columns */
    public function upgrade_SiteColumn(): void
    {
        $contextManager = ServiceContainer::getService(ContextManager::class);
        $languageContext = Contexts::get(LanguageContext::class);

        $defaultCurrency = Contexts::get(CurrencyContext::class)->getDefaultId();

        // pridam id sloupec
        sqlQuery('ALTER TABLE products_watchdog ADD COLUMN id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST');
        // pridam sites a currency context
        sqlQuery('ALTER TABLE products_watchdog ADD COLUMN id_site INT NOT NULL AFTER id');
        sqlQuery('ALTER TABLE products_watchdog ADD COLUMN currency VARCHAR(3) DEFAULT NULL AFTER price');

        $sites = Mapping::mapKeys(sqlQueryBuilder()
            ->select('id, domain, id_language')
            ->from('sites')
            ->sendToMaster()
            ->execute(), fn ($k, $v) => [$v['domain'].'-'.$v['id_language'], $v['id']]);

        $defaultSiteId = $sites[$contextManager->getDomainFromLanguage($languageContext->getDefaultId()).'-'.$languageContext->getDefaultId()] ?? reset($sites);

        // nagenerovat default hodnoty pro id_site a currency
        $cases = [];
        foreach ($languageContext->getSupported() as $language) {
            $langId = $language->getId();
            $domain = $contextManager->getDomainFromLanguage($langId);
            $siteId = $sites[$domain.'-'.$langId] ?? $defaultSiteId;
            $cases[] = "WHEN '{$langId}' THEN '{$siteId}'";
        }

        sqlQuery('UPDATE products_watchdog pw
            JOIN users u ON u.id = pw.id_user
            SET pw.id_site = (
                CASE u.id_language '.implode('', $cases).' ELSE '.$defaultSiteId.' END
            )');

        $currencyField = findModule(\Modules::CURRENCIES) ? "COALESCE(IF(u.currency='', NULL, u.currency), '{$defaultCurrency}')" : "'{$defaultCurrency}'";

        sqlQuery('UPDATE products_watchdog pw
            JOIN users u ON u.id = pw.id_user
            SET pw.currency = '.$currencyField.'
            WHERE pw.price IS NOT NULL');

        // pridam foreign key k id_site
        sqlQuery('ALTER TABLE products_watchdog ADD FOREIGN KEY (id_site) REFERENCES `sites` (id) ON UPDATE CASCADE ON DELETE CASCADE');

        $this->upgradeOK();
    }

    public function check_CurrencyColumnForeignKey(): bool
    {
        return findModule(\Modules::CURRENCIES) && $this->checkForeignKeyExists('products_watchdog', 'currency');
    }

    /** watchdog: add `currency` foreign key */
    public function upgrade_CurrencyColumnForeignKey(): void
    {
        sqlQuery('ALTER TABLE products_watchdog ADD FOREIGN KEY (currency) REFERENCES `currencies` (id) ON UPDATE CASCADE');

        $this->upgradeOK();
    }
}
