<?php

/**
 * iCMS - i Content Management System
 * Copyright (c) 2007-2017 iCMSdev.com. All rights reserved.
 *
 * @author icmsdev <master@icmsdev.com>
 * @site https://www.icmsdev.com
 * @licence https://www.icmsdev.com/LICENSE.html
 */
defined('iPHP') or exit('What are you doing?');

abstract class AdmincpBase extends AdmincpView
{
    public $config      = array();
    public $extends     = array();
    public $SPIDER      = array();
    public $ACCESC_BASE = array(
        'ADD'    => '新增',
        'MANAGE' => '管理',
        'EDIT'   => '编辑',
        'DELETE' => '删除',
    );
    public static $appConfig  = array();
    public static $appId      = 0;
    public static $primaryKey = 'id';
    public static $orderBySql = null;
    public static $orderBy    = array();
    public static $POST       = array();
    public static $GET        = array();
    public static $BATCH      = array();

    public function __construct($appid = null)
    {
        self::$appId     = $appid ?: Admincp::$APPID;
        self::$appConfig = Config::get(Admincp::$APP);
        self::$POST      = Request::post();
        self::$GET       = Request::get();

        $this->id        = (int)Request::get('id');
        $this->config    = self::$appConfig;
        $this->extends   = Config::scan(Admincp::$APP_NAME . '.' . Admincp::$APP_DO, Admincp::$APP, false);
    }
    //应用编辑内容时回调
    public static function add($that, $method, &$data)
    {
        // $class = get_class($that);
        $appId = self::$appId;
        $id    = $data[self::$primaryKey];
        $data['cid'] && Node::getAppMeta($data['cid']);
        AppsMeta::get($appId, $id);
        $apps = Apps::get($appId);
        if ($apps['fields']) {
            Content::model($apps);
            if (ContentDataModel::$unionKey) {
                $where[ContentDataModel::$unionKey] = $id;
                $_data = ContentDataModel::getData($where);
                is_array($_data) && $data = array_merge($data, $_data);
            }
            FormerApp::add($apps, $data, true);
        }
    }
    //应用保存内容时回调
    public static function save($that, $method, $data)
    {
        $class = get_class($that);
        $appId = self::$appId;
        $id    = $data[self::$primaryKey];
        AppsMeta::save($appId, $id);

        $apps = Apps::get($appId);
        if ($apps['fields']) {
            Content::model($apps);
            FormerApp::save($apps, $id);
        }
        //Spider::callback
        iPHP::callback(array("Spider", "callback"), array($that, $id));
    }
    /**
     * [管理列表]
     */
    public function do_iCMS()
    {
        $args = func_get_args();
        if (method_exists($this, 'do_index')) {
            $method = 'do_index';
        } elseif (method_exists($this, 'do_manage')) {
            $method = 'do_manage';
        }
        return call_user_func_array(array($this, $method), $args);
    }
    public function do_config()
    {
        $appid = static::$appId;
        if ($GLOBALS['CONFIG_VAPPID']) {
            $GLOBALS['CONFIG_APPID'] = $appid;
            $appid = Config::VAPPID;
        }
        Config::app($appid);
    }

    /**
     * 保存配置
     */
    public function ACTION_save_config()
    {
        Config::$data = Request::post('config');
        $appid = static::$appId;
        if ($GLOBALS['CONFIG_VAPPID']) {
            $GLOBALS['CONFIG_APPID'] = $appid;
            $appid = Config::VAPPID;
        }
        Config::save($appid);
    }
    public static function error($msg, $state = 'error')
    {
        return Admincp::exception($msg, $state);
    }
    /**
     * [alert description]
     *
     * @return iJson::error
     */
    public static function alert($msg)
    {
        return Admincp::exception($msg, 'alert');
    }
    /**
     * [success description]
     *
     * @return iJson::success
     */
    public static function success()
    {
        $args = func_get_args();
        if (Request::param('frame') || Request::post() || Request::file()) {
            iJson::$jsonp = 'AdmSuccess';
            Request::param('modal') && iJson::$jsonp = 'ModalSuccess';
        }

        Request::isAjax() && iJson::$jsonp = false;

        DB::commit();
        return call_user_func_array(array('iJson', 'success'), $args);
    }
    public static function orderByOption($array, $by = "DESC")
    {
        $opt = '';
        $byText = ($by == "ASC" ? "升序" : "降序");
        foreach ($array as $key => $value) {
            $opt .= '<option value="' . $key . ' ' . $by . '">' . $value . ' [' . $byText . ']</option>';
        }
        return $opt;
    }
    public static function setOrderBy($array = null)
    {
        empty($array) && $array = array('id' => "ID");

        list($order, $by) = explode(' ', $_GET['orderby']);

        if ($by != 'DESC' && $by != 'ASC') {
            $by = 'DESC';
        }

        $default = array_keys($array);
        self::$orderBySql = isset($array[$order]) ?
            (' `' . $order . '` ' . $by) :
            $default[0] . " DESC";

        self::$orderBy = array(
            'DESC' => self::orderByOption($array, "DESC"),
            'ASC'  => self::orderByOption($array, "ASC")
        );
        return self::$orderBySql;
    }
    public static function setWhere($data, &$where, $fields)
    {
        foreach ($data as $key => $value) {
            if ($_key = $fields[$key]) {
                $where[$_key] = $value;
            } elseif (in_array($key, $fields)) {
                $where[$key] = $value;
            }
        }
    }

    public function formSubmit()
    {
        include self::view("widget/form.submit", 'admincp');
    }

    public function formFoot()
    {
        include self::view("widget/form.footer", 'admincp');
    }
    public function appExtends($data = null)
    {
        include self::view("widget/extends", "apps");
    }
    public function actionBtns($data, $node, $app = null)
    {
        is_null($app) && $app = Admincp::$APP_NAME;
        $className = get_called_class();
        //app/*/test.manage.action*.json
        $pattern = sprintf("{%s,all}.manage.action*", $app);
        if($className =='ContentAdmincp'){
            $pattern = sprintf("{%s,content,all}.manage.action*", $app);
        }
        // var_dump($pattern);
        if (!$actions = $GLOBALS[$pattern]) {
            $actions = (array)Etc::many('*', $pattern, true);
            if ($actions) {
                foreach ($actions as $key => $value) {
                    $attr = [];
                    if ($value['icon']) {
                        if (strpos($value['icon'], ' ') === false) {
                            $value['icon'] = 'fa fa-' . $value['icon'];
                        }
                        $value['icon'] .= ' fa-fw';
                        $value['icon'] = sprintf('<i class="%s"></i>', $value['icon']);
                    }
                    if ($value['data-toggle']) {
                        $attr[] = sprintf('data-toggle="%s"', $value['data-toggle']);
                    }
                    if ($attr) {
                        $value['attr'] = implode(' ', $attr);
                    }
                    $actions[$key] = $value;
                }
            }
            $GLOBALS[$pattern] = $actions;
        }
        if($actions){
            $json = json_encode($actions);

            $json = preg_replace_callback("/\{\\\$(v|c|s)\.(.*?)\}/", function ($item) use ($data) {
                if ($item[1] == 'c') {
                    return constant($item[2]);
                } elseif ($item[1] == 's') {
                    // var_dump($item,self::$appId);
                    $class = get_called_class();
                    return $class::${$item[2]};
                } elseif ($item[1] == 'v') {
                    return $data[$item[2]];
                }
            }, $json);
            $actions = json_decode($json, true);
        }
        include self::view("widget/manage.action", 'admincp');
    }
    public function ACTION_batch()
    {
        $actions = array();
        return self::batch($actions);
    }
    public static function batchEtc($app = null)
    {
        is_null($app) && $app = Admincp::$APP_NAME;
        $app  = self::$BATCH['etc.app'] ?: $app;
        $method  = self::$BATCH['etc.method'] ?: 'manage';
        //app/*/test.manage.batch*.json
        $pattern = sprintf("%s.%s.batch*", $app, $method);
        $many1 = (array)Etc::many('*', $pattern, true);
        $many2 = [];
        $className = get_called_class();
        $parent = get_parent_class($className);
        if ($parent == 'NodeAdmincp') {
            //app/*/node.manage.batch*.json
            $pattern = sprintf("node.%s.batch*", $method);
            $many2 = (array)Etc::many('*', $pattern, true);
        }
        $actions = array_merge($many1, $many2);
        if ($actions) foreach ($actions as $key => $item) {
            $name = $item['name'];
            self::$BATCH['etc.name'] && $name = str_replace("{name}", self::$BATCH['etc.name'], $name);
            $actions[$key]['name'] = str_replace("{name}", Admincp::$APP_DATA['title'], $name);
            if (!AdmincpAccess::batch($key)) {
                unset($actions[$key]);
            }
        }
        return $actions;
    }
    //批量操作其它UI
    public static function batchHtml()
    {
        // var_dump('batchHtml');
        // self::$BATCH['data'] = true;
        // $actions = Admincp::$APP_INSTANCE->ACTION_batch();
        $actions = self::batchEtc();
        $app = Admincp::$APP_NAME;
        if ($actions) foreach ($actions as $key => $item) {
            if ($item['view']) {
                $view = $item['view'];
                ///app/article/views/batch.sss.html
                $path = self::view('batch.' . $view[0], $view[1] ?: $app);
                if (is_file($path)) {
                    include $path;
                }
            }
        }
    }
    //批量操作菜单
    public static function batchMenu()
    {
        // self::$BATCH['data'] = true;
        // $actions = Admincp::$APP_INSTANCE->ACTION_batch();
        $actions = self::batchEtc();
        $enable  = isset(self::$BATCH['enable']) ? self::$BATCH['enable'] : true;
        include self::view("widget/batch", 'admincp');
    }
    public static function batch($default, $title = null, $field = 'id', $type = 'intval')
    {

        $actions = self::batchEtc();
        // if (self::$BATCH['data']) {
        //     return $actions;
        // }
        // var_dump($actions,iDebug::$DATA['batchEtc'],Admincp::$APP_NAME);
        $app = Admincp::$APP_NAME;
        $param = self::batchParam($title, $field, $type);
        $batch = $param[2];
        $item = $actions[$batch];
        if ($item['post']) {
            foreach ($item['post'] as $key => $pkey) {
                is_numeric($key) && $key = $pkey;
                $post[$key] = Request::post($pkey);
            }
            array_push($param, $post);
        }
        $call = $item['call'] ?: $batch;
        $callbale = $default[$call] ?: $call;
        is_callable($callbale) or self::alert('[' . $callbale . ']不存在');
        $result = iPHP::callback($callbale, $param, E_USER_ERROR);

        $title = $item['title'] ?: $item['name'];
        empty($title) && $title = Admincp::$APP_DATA['title'];
        if (is_bool($result)) {
            return [$result, $title];
        } elseif (is_array($result)) {
            return $result;
        } else {
            return $result ?: $title;
        }
    }
    public static function setBatch($key, $value)
    {
        self::$BATCH[$key] = $value;
    }
    public static function batchParam($title = null, $field = 'id', $type = 'intval')
    {
        $msg = '请选择要操作的' . ($title ?: '项目');
        $idArray = (array) $_POST[$field];
        $idArray or self::alert($msg);
        $type && $idArray = array_map($type, $idArray);
        $ids     = implode(',', $idArray);
        $batch   = $_POST['batch'];
        return array($idArray, $ids, $batch);
    }
    public static function showed($show, $data,$node = null)
    {
        $showed = (bool)(isset($show) ? $show : true);
        if (is_array($show)) {
            foreach ($show as $sk => $sv) {
                $dv = $data[$sk];
                if (is_array($sv)) {
                    $showed = version_compare($dv, $sv[1], $sv[0]) && $showed;
                } else {
                    $showed = ($dv == $sv) && $showed;
                }
            }
        } elseif ($show) {
            if (strpos($show, '::') !== false) {
                $class = get_called_class();
                $show = str_replace('self::', $class . '::', $show);
                $showed = call_user_func_array($show, [$data,$node]);
            }
        }
        return $showed;
    }

    // abstract protected function do_iCMS();
    // abstract protected function do_add();
    // abstract protected function do_manage();
    // abstract protected function do_batch();
    // abstract protected function ACTION_save();

    /**
     * 不存在静态方法，调用 Admincp 同名方法
     *
     * @param String $method
     * @param Array $params
     * @return void
     */
    // public static function __callStatic($method, $params)
    // {
    //     return  Admincp::proxy($method, $params);
    // }
}
