<?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\widgets;

use iron\web\UploadAsset;
use yii\base\InvalidArgumentException;
use yii\base\Model;
use yii\helpers\Html;
use yii\web\NotFoundHttpException;
use yii\widgets\InputWidget;
use yii;

/***
 * @author iron <weiriron@gmail.com>
 * @created Sep 11, 2019
 */
class Upload extends InputWidget
{
    /**
     * @var string
     * 上传url
     */
    public $url;
    /**
     * @var bool
     * 是否支持多图
     */
    public $multiple;
    /**
     * @var string
     * 文件保存后ajax异步操作(如操作数据库)
     */
    public $afterSave;
    /**
     * @var bool
     * 显示预览
     */
    public $showPreviews;
    /**
     * @var integer
     * 最大数量
     */
    public $maxCount;
    /**
     * @var string
     * 支持上传的文件类型
     */
    public $acceptFile;
    /**
     * @var int
     * 最大现在尺寸(kB)
     */
    public $maxSize;
    /**
     * @var array
     * 预览设置
     */
    public $previewConfig;
    /**
     * @var string
     * 删除图片
     */
    public $deleteUrl;
    /**
     * @var bool
     * 显示删除按钮
     */
    public $showDelete;
    /**
     * @var int
     * 预览框大小
     */
    public $statusBarWidth;
    /**
     * @var int
     * 拉拽框大小
     */
    public $dragdropWidth;
    /**
     * @var
     * 数据模型
     */
    public $model;
    /**
     * @var
     * 填入结果的参数
     */
    public $fillInAttribute;
    /**
     * @var
     * 填入结果的输入框id
     */
    private $fillInId;
    /**
     * @var string Regular expression used for attribute name validation.
     * @since 2.0.12
     * 属性匹配规则
     */
    private static $attributeRegex = '/(^|.*\])([\w\.\+]+)(\[.*|$)/u';

    /**
     * @throws NotFoundHttpException
     * @throws \yii\base\InvalidConfigException
     * 初始化参数
     */
    public function init()
    {
        parent::init();
        if (!$this->url) {
            throw new NotFoundHttpException('(upload) 必须配置上传url');
        }
        if (isset($this->previewConfig['url'])) {
            $this->previewConfig['height'] = $this->previewConfig['height'] ?? '80px';
            $this->previewConfig['width'] = $this->previewConfig['width'] ?? '80px';
        }
        $this->showPreviews = $this->previewConfig['url'] ? 'true' : 'false';//默认不显示预览
        $this->showPreviews = $this->showPreviews ?: 'false';//默认关闭预览
        $this->statusBarWidth = $this->statusBarWidth ?: 300;//默认关闭预览
        $this->dragdropWidth = $this->dragdropWidth ?: 800;//默认关闭预览
        $this->acceptFile = $this->acceptFile ?: '*';//默认无限制文件类型
        $this->maxCount = $this->maxCount ?: 10;//默认数量限制十张图
        $this->showDelete = $this->deleteUrl ? 'true' : 'false';//默认不显示删除按钮
        $this->maxSize = $this->maxSize ? $this->maxSize *= 1024 : 2 * 1024 * 1024;//默认限制2M大小;
        if (!$this->fillInAttribute) {
            throw new NotFoundHttpException('(fillInAttribute) 必须配置填入参数');
        }
        if (!$this->model) {
            throw new NotFoundHttpException('(model) 必须配置model');
        }
        $this->fillInId = self::getInputId($this->model, $this->fillInAttribute);
    }

    /**
     * @return string
     * 执行
     */
    public function run()
    {
        $this->registerAsset();
        return $this->renderUploadHtml();
    }

    /**
     * 注册js和css
     */
    protected function registerAsset()
    {
        $view = $this->getView();
        UploadAsset::register($view);
        $js = <<< SCRIPT
            $("#upload-file-{$this->attribute}").uploadFile({
            url:"upload",
            returnType: "json",
            multiple:true,
            dragDrop:true,
            fileName:"file",
            statusBarWidth:{$this->statusBarWidth},
            dragdropWidth:{$this->dragdropWidth},
            dragDropStr:"<span><b>拖动上传</b></span>",
            sizeErrorStr:"超过最大尺寸限制",
            maxFileCountErrorStr:"超过最大上传数量",
            uploadErrorStr:"上传失败",
            maxFileCount:"{$this->acceptFile}",
            maxFileCount:{$this->maxCount},
            maxFileSize:{$this->maxSize},
            showPreview:{$this->showPreviews},
            previewHeight:"{$this->previewConfig['height']}",
            previewWidth:"{$this->previewConfig['width']}",
            showDelete: {$this->showDelete},
             onSuccess: function (files, data) {
                $.ajax({
                    url: "{$this->afterSave}",
                    dataType: "json",
                    data: {data: data, fileName: files},
                    success: function(data)
                    {
                            var imageval = $('#{$this->fillInId}').val();
                            if(imageval == '' || imageval == 0){
                                $('#{$this->fillInId}').val(data);
                            }else{
                                $('#{$this->fillInId}').val($('#{$this->fillInId}').val()+','+data);
                            }
                    }
                });
            },
            onLoad:function(obj)
            {
            $.ajax({
                cache: false,
                url: "{$this->previewConfig['url']}",
                dataType: "json",
                success: function(data)
                {
                    for(var i=0;i<data.length;i++)
                    {
                        obj.createProgress(data[i]["name"],data[i]["path"],data[i]["size"]);
                    }
                }
            });
        },
        deleteCallback: function (data, pd) {
            $.ajax({
                url: '{$this->deleteUrl}',
                data: {data: data, imgid: $('#{$this->fillInId}').val()},
                success: function(data)
                {
                    $('#{$this->fillInId}').val(data);
                },
            });
//            for (var i = 0; i < data.length; i++) {
//                $.post("{$this->deleteUrl}", {op: "delete",name: data[i]},
//                    function (resp,textStatus, jqXHR) {
//                        
//                    });
//            }
            pd.statusbar.hide(); //You choice.
        },
        
    });
SCRIPT;
        $view->registerJs($js);
    }

    /**
     * @return string
     * 渲染html
     */
    protected function renderUploadHtml()
    {
        return '<div class="box-body">
                    <div id="upload-file-' . $this->attribute . '">
                        <div class="ajax-upload-dragdrop" style="vertical-align: top; width: 600px;">
                            <div class="ajax-file-upload" style="position: relative; overflow: hidden; cursor: default;">Upload
                                <form method="POST" action="upload.php" enctype="multipart/form-data" style="margin: 0px; padding: 0px;">
                                    <input type="file" id="ajax-upload-id-1573635462220" name="myfile[]" accept="*" multiple="" style="position: absolute; cursor: pointer; top: 0px; width: 100%; height: 100%; left: 0px; z-index: 100; opacity: 0;">
                                </form>
                            </div>
                            <span><b>Drag &amp; Drop Files</b></span>
                        </div>
                    <div>
                </div>';
    }

    /**
     * @param $model
     * @param $attribute
     * @return string
     * 获取要填入属性的输入框name
     */
    private static function getInputName($model, $attribute)
    {
        $formName = $model->formName();
        if (!preg_match(static::$attributeRegex, $attribute, $matches)) {
            throw new InvalidArgumentException('Attribute name must contain word characters only.');
        }
        $prefix = $matches[1];
        $attribute = $matches[2];
        $suffix = $matches[3];
        if ($formName === '' && $prefix === '') {
            return $attribute . $suffix;
        } elseif ($formName !== '') {
            return $formName . $prefix . "[$attribute]" . $suffix;
        }

        throw new InvalidArgumentException(get_class($model) . '::formName() cannot be empty for tabular inputs.');
    }

    /**
     * @param $model
     * @param $attribute
     * @return mixed
     * 获取要填入属性的输入框id
     */
    private static function getInputId($model, $attribute)
    {
        $charset = Yii::$app ? Yii::$app->charset : 'UTF-8';
        $name = mb_strtolower(static::getInputName($model, $attribute), $charset);
        return str_replace(['[]', '][', '[', ']', ' ', '.'], ['', '-', '-', '', '-', '-'], $name);
    }
}