<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonCommon\Classes\Installation\Order;

use Shopware\Plugins\ViisonCommon\Classes\Installation\SQLHelper;
use \Zend_Db_Adapter_Abstract;

class OrderStateInstallationHelper
{
    /**
     * @var SQLHelper $sqlHelper
     */
    private $sqlHelper;

    /**
     * @var Zend_Db_Adapter_Abstract $db
     */
    private $db;

    /**
     * @param Zend_Db_Adapter_Abstract $db
     */
    public function __construct(Zend_Db_Adapter_Abstract $db)
    {
        $this->db = $db;
        $this->sqlHelper = new SQLHelper($db);
    }

    /**
     * Ensures a order state exists in the database. Existing states with the same name and group will be updated,
     * otherwise a new state will be created.
     *
     * @param string $name
     * @param string $description
     * @param int $position
     * @param bool $sendMail (default: false)
     */
    public function ensureOrderStateExists($name, $description, $position, $sendMail = false)
    {
        $this->ensureStateExists($name, $description, $position, 'state', $sendMail);
    }

    /**
     * Ensures a payment state exists in the database. Existing states with the same name and group will be updated,
     * otherwise a new state will be created.
     *
     * @param string $name
     * @param string $description
     * @param int $position
     * @param bool $sendMail (default: false)
     */
    public function ensurePaymentStateExists($name, $description, $position, $sendMail = false)
    {
        $this->ensureStateExists($name, $description, $position, 'payment', $sendMail);
    }

    /**
     * Ensures a specific state exists in the s_core_states table. If a similar state (name and group) already exists,
     * update remaining values, otherwise create new state.
     *
     * Remark: since IDs are not auto incremented, we fetch the highest id and increment it manually.
     *
     * @param string $name
     * @param string $description
     * @param int $position
     * @param string $group ['state', 'payment']
     * @param bool $sendMail
     */
    private function ensureStateExists($name, $description, $position, $group, $sendMail)
    {
        if ($this->sqlHelper->doesRowExist('s_core_states', ['name', 'group'], [$name, $group])) {
            // Update existing name-group combination
            $this->db->query(
                'UPDATE s_core_states
                SET description = :description, position = :position, mail = :mail
                WHERE name = :name
                AND s_core_states.group = :group',
                [
                    ':description' => $description,
                    ':position' => $position,
                    ':mail' => $sendMail,
                    ':name' => $name,
                    ':group' => $group,
                ]
            );
        } else {
            // Fetch and increment id and create new state
            $maxId = intval($this->db->fetchOne('SELECT max(id) FROM s_core_states'));
            $this->db->query(
                'INSERT INTO s_core_states
                VALUES (:id, :name, :description, :position, :group, :mail)',
                [
                    ':id' => $maxId + 1,
                    ':name' => $name,
                    ':description' => $description,
                    ':position' => $position,
                    ':group' => $group,
                    ':mail' => $sendMail,
                ]
            );
        }
    }
}
