<?php

/**
 * This file contains the \QUI\System\Console\Tools\CreateProject
 */

namespace QUI\System\Console\Tools;

use Exception;
use QUI;

use function mb_strpos;
use function mb_strtolower;
use function str_replace;
use function trim;

/**
 * Set attributes for a selection of Sites
 */
class SetSiteAttributes extends QUI\System\Console\Tool
{
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->setName('quiqqer:set-site-attributes')
            ->setDescription('Set attributes for a selection of Sites')
            ->addArgument(
                'projectname',
                'Name of the project',
                'pname'
            )
            ->addArgument(
                'projectlang',
                'Language of the project',
                'plang'
            );
    }

    /**
     * (non-PHPdoc)
     *
     * @throws QUI\Exception
     * @see \QUI\System\Console\Tool::execute()
     */
    public function execute(): void
    {
        $Projects = QUI::getProjectManager();

        // project name
        $projectname = $this->getArgument('projectname');
        $projectlang = $this->getArgument('projectlang');

        try {
            $Project = $Projects->getProject($projectname, $projectlang);
        } catch (Exception) {
            $this->writeLn("Could not load project $projectname ($projectlang)");
            $this->execute();

            return;
        }

        $this->writeLn("Site query (SQL): WHERE ");
        $siteQuery = trim($this->readInput());

        $QueryBuilder = QUI::getQueryBuilder()
            ->select('id')
            ->from(QUI::getDBProjectTableName('sites', $Project))
            ->where($siteQuery);

        $this->writeLn("\nQuerying sites: " . $QueryBuilder->getSQL());

        try {
            $siteIds = $QueryBuilder->executeQuery()->fetchAllAssociative();
        } catch (\Throwable $Exception) {
            QUI\System\Log::writeException($Exception);
            $this->writeLn("\n\nERROR: Query failed -> " . $Exception->getMessage());
            exit(1);
        }

        $this->writeLn("Found " . count($siteIds) . " sites.");

        // Set site attributes
        $this->writeLn("\n====== Set site attributes ======");

        $placeholderDesc = [
            'id' => 'Site ID',
            'title' => 'Site title',
            'true' => 'Boolean true',
            'false' => 'Boolean false'
        ];

        $this->writeLn("\nThe following placeholders can be used\n");

        foreach ($placeholderDesc as $placeholder => $desc) {
            $this->writeLn("[$placeholder] -> $desc");
        }

        $attributes = [];

        do {
            $this->writeLn("\nSet attribute (key): ");
            $attrKey = trim($this->readInput());

            $this->writeLn("Value: ");
            $attrVal = trim($this->readInput());

            $attributes[$attrKey] = $attrVal;

            $this->writeLn("Set another attribute? (Y/n): ");
            $setNew = $this->readInput();

            if (mb_strtolower($setNew) === 'n') {
                break;
            }
        } while (true);


        $this->writeLn("\nThe following site attributes will be set:\n");

        foreach ($attributes as $k => $v) {
            $this->writeLn("$k => $v");
        }

        $this->writeLn("\nIs this OK? (Y/n): ");
        $confirm = $this->readInput();

        if (mb_strtolower($confirm) === 'n') {
            $this->writeLn("Exit.");
            exit(0);
        }

        $SystemUser = QUI::getUsers()->getSystemUser();

        foreach ($siteIds as $row) {
            $siteId = $row['id'];
            $this->writeLn("\nEdit Site #$siteId...");

            try {
                $Site = new QUI\Projects\Site\Edit($Project, $siteId);
                $this->write(" OK!");
            } catch (Exception $Exception) {
                QUI\System\Log::writeException($Exception);
                $this->write(" ERROR: " . $Exception->getMessage());
                continue;
            }

            foreach ($attributes as $k => $v) {
                $output = $v;

                foreach (array_keys($placeholderDesc) as $placeholder) {
                    $placeholder = '[' . $placeholder . ']';
                    if (mb_strpos((string)$v, $placeholder) === false) {
                        continue;
                    }

                    switch ($placeholder) {
                        case '[id]':
                            $v = str_replace($placeholder, (string)$Site->getId(), (string)$v);
                            $output = $v;
                            break;

                        case '[title]':
                            $v = str_replace($placeholder, $Site->getAttribute('title'), (string)$v);
                            $output = $v;
                            break;

                        case '[true]':
                            $v = true;
                            $output = 'true (bool)';
                            break;

                        case '[false]':
                            $v = false;
                            $output = 'false (bool)';
                            break;
                    }
                }

                $this->writeLn("Set \"$k\" to $output");

                try {
                    $this->writeLn("\nSaving Site...");
                    $Site->setAttribute($k, $v);
                    $Site->unlockWithRights();
                    $Site->save($SystemUser);

                    $this->write(" OK!");
                } catch (Exception $Exception) {
                    QUI\System\Log::writeException($Exception);
                    $this->write(" ERROR: " . $Exception->getMessage());
                }
            }
        }

        $this->writeLn("\n\nFinished.\n\n");
        exit(0);
    }
}
