<?php

class Am_Plugins_Payment extends Am_Plugins
{
    /** @var Am_Paysystem_Description[] */
    protected $list = [];
    protected $loaded = false;

    public function getAvailable()
    {
        $_ = parent::getAvailable();
        unset($_['free']); // hide free plugin from list - it is always enabled
        return $_;
    }

    public function getEnabled()
    {
        return array_unique(parent::getEnabled() + ['free']);
    }

    /**
     * @return bool
     */
    public function haveCcPluginsInTheList(array $plugins)
    {
        $this->getAvailable();
        foreach ($plugins as $_)
        {
            if (strpos($this->_available[$_], '/cc/')!== false) return true;
            if (strpos($this->_available[$_], '\\cc\\')!== false) return true;
        }
        return false;
    }

    public function activate($id, $errorHandling = self::ERROR_EXCEPTION, $commitToConfigAndDbSync = false)
    {
        if ($this->haveCcPluginsInTheList(array_merge($this->getEnabled(), [$id])))
        {
            $_ = $this->_di->modules->activate('cc', $errorHandling, $commitToConfigAndDbSync);
            if ($_ !== true)
                return $_;
        }
        return parent::activate($id, $errorHandling, $commitToConfigAndDbSync);
    }

    public function deactivate(
        $id,
        $errorHandling = self::ERROR_EXCEPTION,
        $commitToConfig = false,
        $cleanConfig = false
    ) {
        $ret = parent::deactivate($id, $errorHandling, $commitToConfig, $cleanConfig);
        if ($ret === true)
        {
            $list = $this->getEnabled();
            array_remove_value($list, $id);
            if (!$this->haveCcPluginsInTheList($list))
                $this->_di->modules->deactivate('cc', $errorHandling, $commitToConfig);
        }
        return $ret;
    }

    /**
     * Trigger loading of all plugins to get entries added.
     */
    protected function loadAllEnabled()
    {
        if ($this->loaded) {
            return;
        }
        $this->loadEnabled();
        $this->getAllEnabled();
        $this->loaded = true;
    }

    /**
     * @return Am_Paysystem_Description[]
     */
    public function getList()
    {
        return $this->list;
    }

    /**
     * @param Am_Paysystem_Description $record
     */
    public function add($record)
    {
        $this->list[] = $record;
    }

    /**
     * @return Am_Paysystem_Description|null
     */
    public function getDescription($id)
    {
        $this->loadAllEnabled();
        foreach ($this->list as $p) {
            if ($p->getId() == $id) {
                return $p;
            }
        }
        return null;
    }

    /**
     * @return Am_Paysystem_Description[]
     */
    public function getAll()
    {
        $this->loadAllEnabled();
        return $this->list;
    }

    /**
     * @return Am_Paysystem_Description[]
     */
    public function getAllPublic()
    {
        $ret = [];
        $free = null;
        foreach ($this->getAll() as $p) {
            if ($p->isPublic()) {
                if ($p->getId() == 'free') {
                    $free = $p;
                } else {
                    $ret[] = $p;
                }
            }
        }
        // usually we hide 'free' option, but if no options, we will show it
        if (!$ret && $free) {
            $ret[] = $free;
        }
        return $ret;
    }

    /**
     * @return bool true if enabled and public
     */
    public function isPublic($paysysId)
    {
        foreach ($this->getAll() as $p) {
            if ($p->isPublic() && $p->getId() == $paysysId) {
                return true;
            }
        }
        return false;
    }

    public function getAllPublicAsArrays()
    {
        return array_map(function($p) {return $p->toArray();}, $this->getAllPublic());
    }

    /**
     * @return array key=>title for customers
     */
    public function getOptionsPublic()
    {
        $ret = [];
        foreach ($this->getAllPublic() as $p) {
            $ret[$p->getId()] = $p->getTitle();
        }
        return $ret;
    }

}
