<?php

namespace KupShop\AdminBundle\Resources\script;

use KupShop\AdminBundle\Util\Script\Script;
use KupShop\KupShopBundle\Context\DomainContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\RewriteBundle\Util\Rewrite;
use Query\Operator;

class ChangeURLScript extends Script
{
    /** @var DomainContext */
    protected $domainContext;

    /** @var Rewrite */
    protected $rewrite;

    protected array $change_host = [];
    protected array $change_text = [];

    public function __construct()
    {
        $this->domainContext = ServiceContainer::getService(DomainContext::class);
        $this->rewrite = ServiceContainer::getService(Rewrite::class);
    }

    protected static $name = 'Nahradit v obsahových textech staré URL nebo text';

    protected static $defaultParameters = [
        'tables' => [
            'blocks' => [
                'content',
                'json_content',
            ],
            'blocks_translations' => [
                'content',
                'json_content',
            ],
            'products' => [
                'long_descr',
                'parameters',
            ],
            'products_translations' => [
                'long_descr',
                'parameters',
            ],
            'parameters' => [
                'descr',
            ],
            'parameters_translations' => [
                'descr',
            ],
        ],
        'change_host' => [
            'www.bariholmik.hu' => 'www.woolville.hu',
        ],
        'change_text' => [
            // 'bariholmik.hu' => 'woolville.hu',
        ],
    ];

    public function run(array $arguments)
    {
        if (is_null($arguments['tables'])) {
            $this->log('Chybí argument s tabulkami nebo sloupečky!');

            return false;
        }

        if ($arguments['change_host'] ?? false) {
            $this->change_host = $arguments['change_host'];
        }
        if ($arguments['change_text'] ?? []) {
            $this->change_text = $arguments['change_text'];
        }

        foreach ($arguments['tables'] as $table => $columns) {
            $columnsDB = '';
            foreach ($columns as $column) {
                $columnsDB .= $column.',';
            }
            $columnsDB = rtrim($columnsDB, ',');
            $DB = sqlQuery(
                'SELECT id, '.$columnsDB.'
                FROM '.$table
            );
            $resultDB = $DB->fetchAll();
            if (!is_array($resultDB)) {
                $resultDB = [$resultDB];
            }
            $count = 0;
            foreach ($resultDB as $value) {
                foreach ($columns as $column) {
                    $json = json_decode($value[$column], true);
                    if (count($this->change_text)) {
                        $result = $value[$column];
                        foreach ($this->change_text as $changeTextFrom => $changeTextTo) {
                            $result = str_replace($changeTextFrom, $changeTextTo, $result);
                        }
                        if ($result != $value[$column]) {
                            $this->log('Změna textu: '.$value[$column].' => '.$result);
                        }
                    } elseif (json_last_error() == JSON_ERROR_NONE) {
                        $this->changeJSONURL($json);
                        $result = json_encode($json);
                    } else {
                        $result = $this->changeURLInText($value[$column]);
                    }
                    if ($result != $value[$column]) {
                        sqlQueryBuilder()->update($table)
                            ->directValues([$column => $result])
                            ->where(Operator::equals(['id' => $value['id']]))
                            ->execute();
                        $count++;
                    }
                }
            }
            if (!is_null($count)) {
                $this->log('V tabulce '.$table.' a sloupečku '.$columnsDB.' bylo změněno '.$count.' řádků');
            }
        }
        $this->log('Ok');

        return true;
    }

    public function changeJSONURL(&$json)
    {
        foreach ((array) $json as $key => &$value) {
            if ($value['type'] == 'legacy') {
                $value['settings']['html'] = $this->changeURLInText($value['settings']['html']);
            }
        }
    }

    public function changeURLInText($value)
    {
        $domains = $this->domainContext->getSupported();
        $patern = '/(<a[^>]+href=[\'"])(.+?)([\'"][^>]*>)/im';
        $result = preg_replace_callback(
            $patern,
            function ($match) use ($domains) {
                $replaceDomain = parse_url($match[2]);
                $changeHost = $changePath = false;
                if (isset($replaceDomain['host']) && ($changeHost = ($this->change_host[$replaceDomain['host']] ?? false))) {
                    $replaceDomain['host'] = $this->change_host[$replaceDomain['host']];
                }

                if (!isset($replaceDomain['host']) || in_array($replaceDomain['host'], $domains)) {
                    if (isset($replaceDomain['path']) && $changePath = $this->rewrite->resolve($replaceDomain['path'])) {
                        $replaceDomain['path'] = $changePath;
                    }
                    if ($changePath || $changeHost) {
                        $newPath = $this->unparse_url($replaceDomain);
                        $this->log('Změna URL: '.$match[2].' => '.$newPath);

                        return $match[1].$newPath.$match[3];
                    }
                }

                return $match[0];
            },
            $value
        );

        return $result;
    }

    public function unparse_url($parsed_url)
    {
        $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://' : '';
        $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
        $port = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
        $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
        $pass = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
        $pass = ($user || $pass) ? "{$pass}@" : '';
        $path = isset($parsed_url['path']) ? '/'.ltrim($parsed_url['path'], '/') : '';
        $query = '';
        $fragment = isset($parsed_url['fragment']) ? '#'.$parsed_url['fragment'] : '';

        return "{$scheme}{$user}{$pass}{$host}{$port}{$path}{$query}{$fragment}";
    }
}

return ChangeURLScript::class;
