<?php

/*
 * The MIT License
 *
 * Copyright 2019 Blobt.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

namespace iron\grid;

use Yii;
use yii\helpers\Html;
use yii\helpers\Url;
use blobt\grid\Column;

class ActionColumn extends Column
{

    public $config = [
        [
            'name' => 'view',
            'icon' => 'list',
            'title' => '详情',
        ],
        [
            'name' => 'update',
            'icon' => 'pencil',
            'title' => '修改'
        ],
        [
            'name' => 'delete',
            'icon' => 'trash',
            'title' => '删除',
            'contents' => '确定删除?'
        ]
    ];
    /**
     * @var string 处理的控制器ID
     */
    public $controller;

    /**
     * @var string 按钮模板
     */
    public $template = '';

    /**
     * @var array 以按钮名为键,以匿名函数为值,通过匿名函数返回html,用来控制按钮的表现形式
     * 匿名函数必须遵循以下申明方式:
     *
     * ```php
     * function ($url, $model, $key) {
     *     // return the button HTML code
     * }
     * ```
     *
     * - `$url`: 按钮的跳转路径
     * - `$model`: 每行的模型
     * - `$key`: id值
     *
     * 使用案例:
     * ```php
     * [
     *     'update' => function ($url, $model, $key) {
     *         return $model->status === 'editable' ? Html::a('Update', $url) : '';
     *     },
     * ],
     *
     */
    public $buttons = [];

    /** @var array 和上述$buttons功能类似,只是匿名函数返回布尔,只控制是否展示
     * 匿名函数必须遵循以下申明方式:
     *
     * ```php
     * function ($model, $key, $index) {
     *     return $model->status === 'editable';
     * }
     * ```
     *
     * 使用案例:
     * ```php
     * [
     *     'update' => \Yii::$app->user->can('update'),
     * ],
     * ```
     * @since 2.0.7
     */
    public $visibleButtons = [];

    /**
     * @var callable 匿名函数,用作控制按钮Url
     *
     * 匿名函数必须遵循以下申明方式:
     * ```php
     * function (string $action, mixed $model, mixed $key, integer $index, ActionColumn $this) {
     *     //return string;
     * }
     * ```
     *
     * 如果没有设置,默认使用本类的[[createUrl()]].
     */
    public $urlCreator;

    /**
     * @var array 按钮的html属性
     */
    public $buttonOptions = [];

    /**
     * {@inheritdoc}
     */
    public function init()
    {
        parent::init();
        foreach ($this->config as $config) {
            if (isset($config['contents'])) {
                $options = ['alertify-confirm' => Yii::t('yii', "{$config['contents']}?")];
            } else {
                $options = [];
            }
            if (isset($config['icon'])) {
                $icon = $config['icon'];
            } else {
                $icon = 'th-large';
            }
            if (isset($config['title'])) {
                $title = $config['title'];
            } else {
                $title = $config['name'];
            }
            if (isset($config['hide'])) {
                $this->visibleButtons($config['name'], $config['hide']);
            }
            $this->initButton($config['name'], $icon, $options, $title);
            $this->template .= " {{$config['name']}}";
        }
    }

    /**
     * 初始化按钮
     * @param string $name
     * @param string $iconName
     * @param array $additionalOptions 附加html属性
     */
    protected function initButton($name, $iconName, $additionalOptions = [], $title = '')
    {
        $this->buttons[$name] = function ($url, $model, $key) use ($name, $iconName, $additionalOptions, $title) {
            $title = $title ?: Yii::t('yii', $name);
            $options = array_merge([
                'title' => $title,
                'aria-label' => $title,
                'data-pjax' => '0',
            ], $additionalOptions, $this->buttonOptions);
            $icon = Html::tag('span', '', ['class' => "oi oi-$iconName"]);
            return Html::a($icon, $url, $options);
        };
    }

    protected function visibleButtons($name, $config)
    {
        $this->visibleButtons[$name] = function ($model, $key, $index) use ($config) {
            $attributes = $config['attributes'];
            $values = $config['values'];
            if (isset($config['rule']) && $config['rule'] == 'or') {
                foreach ($attributes as $k => $attribute) {
                    if ($model->$attribute  == $values[$k]) {
                        return false;
                    }
                }
                return true;
            }else{
                foreach ($attributes as $k => $attribute) {
                    if ($model->$attribute != $values[$k]) {
                        return true;
                    }
                }
                return false;
            }

        };
    }

    /**
     * 通过给定的action和model创建一个URL.
     *
     * @param string $action 按钮名
     * @param \yii\db\ActiveRecordInterface $model 数据模型
     * @param mixed $key 模型的ID
     * @param int $index 行号
     * @return string the created URL
     */
    public function createUrl($action, $model, $key, $index)
    {
        if (is_callable($this->urlCreator)) {
            return call_user_func($this->urlCreator, $action, $model, $key, $index, $this);
        }

        $params = is_array($key) ? $key : ['id' => (string)$key];
        $params[0] = $this->controller ? $this->controller . '/' . $action : $action;

        return Url::toRoute($params);
    }

    /**
     * {@inheritdoc}
     */
    protected function renderDataCellContent($model, $key, $index)
    {
        return preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($model, $key, $index) {
            $name = $matches[1];

            if (isset($this->visibleButtons[$name])) {
                $isVisible = $this->visibleButtons[$name] instanceof \Closure ? call_user_func($this->visibleButtons[$name], $model, $key, $index) : $this->visibleButtons[$name];
            } else {
                $isVisible = true;
            }

            if ($isVisible && isset($this->buttons[$name])) {
                $url = $this->createUrl($name, $model, $key, $index);
                return call_user_func($this->buttons[$name], $url, $model, $key);
            }

            return '';
        }, $this->template);
    }

}