<?php

/**
 * +------------------------------------------------------------
 * | 数据入口 (index/controller/Index.php)
 * +------------------------------------------------------------
 * | @author: zhx (10630650@qq.com)
 * | @create_time: 2018-01-09
 * +------------------------------------------------------------
 * | @copyright: CIM (https://cimxx.com)
 * +------------------------------------------------------------
 * | @last_modified_by: zhx
 * | @last_modified_time: 2018-11-23
 * +------------------------------------------------------------
 * | @todo:
 * +------------------------------------------------------------
 */

namespace app\index\controller;

use think\Env;
use think\facade\Hook;
use app\index\model\Fields;
use app\common\controller\Addons;

class Index extends Module
{

    protected function initialize()
    {
        parent::initialize();
        //解析栏目
        self::$columns = \load_columns(0);
        if (!empty(self::$column)) {
            $this->assign('column', self::$column);
            //解析地区
            if (self::$column['model'] == 'info') {
                self::$areas = \load_areas(0);
                if (input('param.area') && isset(self::$areas[input('param.area')])) self::$area = self::$areas[input('param.area')];
                $this->assign('area', self::$area);
            }
            if (empty(self::$column['status']) || (self::$column['parent_id'] != 0 && empty(self::$column['parent']['status']))) self::$column = [];
        }
        if (in_array(self::$sys['action'], ['view', 'column'])) $this->check_login();
    }

    /**
     * 栏目
     */
    public function column($key)
    {
        //检测栏目
        if (!empty(self::$column)) {
            if (request()->isPost()) {
                $post = input('post.');
                $param = input('param.');
                foreach ($param as $k => $v) {
                    if (isset($post[$k])) {
                        if ($post[$k] == '') {
                            unset($post[$k], $param[$k]);
                        } else {
                            if (is_array($post[$k])) $post[$k] = implode('_', $post[$k]);
                        }
                    }
                }
                $this->redirect(url('index/index/column?key=' . $key, array_merge($param, $post)));
            }
            if (self::$column['model'] != 'common') {
                $attr = ['cid' => self::$column['id'], 'model' => self::$column['model'], 'page' => input('param.page', 1), 'limit' => self::$column['setting']['pagesize']];
                $filters = $this->filters('lists');
                $attr['order'] = empty($filters['order']) ? 'update_time desc' : $filters['order'];
                $attr['where'] = $filters['where'];
                $attr['field'] = $filters['fields'];
                $attr['where'][] = ['status', '=', 1];
                $attr['where'][] = ['top_end_time', '<', time()];
                $attr['where'][] = ['delete_time', '=', 0];
                $fields = load_fields(self::$column['id'], 0, 1);
                $this->assign('fields', $fields);
                $rs = $this->query($attr);
                if (!in_array(self::$column['model'], ['pages'])) {
                    $rs = $this->_init_data($rs);
                    $this->init_pager($rs['total'], self::$column['setting']['pagesize']);
                    $this->assign('data', $rs['data']);
                    unset($attr['page']);
                } else {
                    $this->assign('data', $rs);
                }
            } else {
                if (!isset(self::$column['setting']['template']['column']) || !template_exists('column/' . self::$column['setting']['template']['column'])) return $this->_404();
            }
            $tpl = $this->_template('column');
            return view($tpl);
        }
        $this->filters('lists');
        //检测模板
        if (template_exists($key)) return view(template_exists($key));
        return $this->_404();
    }

    /**
     * 搜索
     */
    public function search()
    {
        if (empty(input('param.keyword'))) $this->redirect(url('/'));
        if (!empty(input('get.'))) $this->redirect(url('index/index/search', input('get.')));
        $rs = $this->_search(input('param.'));
        if (isset($rs['code']) && $rs['code'] == 0) $this->error([ 'code' => 11009, 'msg'=> $rs['msg'] ]);
        $data = $rs['data'];
        $this->init_pager($data['total']);
        if (!empty($data['data'])) $data['data'] = $this->_init_data($data['data']);
        if (!empty($rs['column'])) {
            $filters['columns'] = ['cid', '栏目', array_column($rs['column'], null, 'column_id')];
        }
        if (!empty($rs['area'])) {
            $filters['area'] = ['area', '地区', array_column($rs['area'], null, 'area_id')];
        }
        $filters = empty($filters) ? [] : $this->init_filters($filters);
        return view('../search', [
            'data' => $data['data'],
            'keyword' => input('param.keyword'),
            'filters' => $filters
        ]);
    }

    /**
     * 详情
     */
    public function view($key, $id = '')
    {
        if (!$id) return $this->column($key);
        $with = '';
        $where = [];
        if (isset(self::$column['model'])) {
            if (isset(self::$models[self::$column['model']]['table'])) {
                $with = join(',', self::$models[self::$column['model']]['table']);
            }
        }
        $rs = model('app\index\model\Data');
        if (!empty(session('admin.id'))) {
            $rs = $rs->withTrashed();
        } else {
            $where[] = ['status', '=', 1];
        }
        $rs = $rs->with($with)->where($where)->find($id);
        if (!empty($rs->image)) $this->_init_image($rs->image);
        if (empty(self::$column)) {
            self::$column = load_column($rs['column_id']);
            if (!empty(self::$column)) {
                $this->assign('column', self::$column);
            } else {
                return $this->_404();
            }
        }
        if (empty($rs)) return $this->_404();
        if ($rs['column_id'] != self::$column['id']) return $this->_404();
        $rs['url'] = $this->_url($id, $key);
        $rs['time'] = time_format($rs['update_time']);
        if (self::$column['model'] == 'info') {
            $rs['info']['expired'] = 0;
            //过期不显示联系方式
            if ($rs->getData('end_time') < time()) {
                $rs['info']['phone'] = '';
                $rs['info']['expired'] = 1;
            }
        }
        if (self::$column['model'] == 'article') {
            if (isset($rs['article']['keywords']) && !empty($rs['article']['keywords'])) {
                $this->assign('tags', tags($rs['article']['keywords']));
            } else {
                $this->assign('tags', []);
            }
        }
        $rs['fields'] = $this->_init_fields((array)$rs['fields'], load_fields($rs['column_id']));
        if (!empty($rs['user_id'])) $rs = $rs->append(['user']);
        $this->assign('rs', $rs->toArray());
        return view($this->_template('view'));
    }

    /**
     * 发布
     */
    public function add($key = '', $id = 0)
    {
        if (!empty(self::$column)) {
            if (self::$column['setting']['group'][self::$user['group_id']]['add_limit'] < 0) {
                $this->error([
                    'msg' => '您暂时不能在《' . self::$column['name'] . '》发布信息。',
                    'code' => 11001
                ]);
            }
        }
        if (!action('index/api/allow_area')) $this->error([
            'msg' => '当前区域禁止发布，请联系管理员...',
            'code' => 11002
        ]);
        if (request()->isPost()) {
            $data = request()->except(['create_time', 'update_time']);
            if (!$id) $data['id'] = $id;
            if (!empty(self::$column['setting']['check']['post_phone_pc']) || !empty(self::$cim['post_phone_pc'])) {
                //验证短信验证码
                if (empty($data['code']) || empty($data['phone'])) $this->error([
                    'msg' => '请填写手机号、短信验证码',
                    'code' => 11003
                ]);
                if (empty(cache($data['phone'])) || cache($data['phone'])['code'] != $data['code'] || cache($data['phone'])['time'] + 180 < time()) $this->error([
                    'msg' => '手机号验证码错误',
                    'code' => 11004
                ]);
                unset($data['code'], $data['verify']);
            } else {
                if (!empty(self::$column['setting']['group'][self::$user['group_id']]['post_check'])) {
                    if (empty($data['captcha']) || !captcha_check($data['captcha'])) $this->error([
                        'msg' => '验证码输入错误',
                        'code' => 11005
                    ]);
                }
            }
            if (!empty($data['image']) || !empty(request()->file())) {
                $upload_limit = self::$column['setting']['group'][self::$user['group_id']]['upload_limit'] ?? 3;
                $count = 0;
                if (!empty($data['image'])) $count += count($data['image']);
                if (!empty(request()->file())) {
                    if (count(request()->file()) == count(request()->file(), 1)) {
                        $count += count(request()->file());
                    } else {
                        $count += (count(request()->file(), 1) - count(request()->file()));
                    }
                }
                if ($data['id']) $count += db('data_image')->where('data_id', '=', $data['id'])->count();
                if ($count > $upload_limit) $this->error([
                    'msg' => "上传图片数量超出系统限制,超出数量:" . ($count - $upload_limit),
                    'code' => 11006
                ]);
            }
            $rs = $this->_add($data);
            if ($rs['code'] == 1) {
                return $this->redirect(url('index/index/add', ['key' => self::$column['key'], 'id' => $rs['id']]));
            } else {
                return $this->error([
                    'msg' => '出了点问题，重新提交试试。问题原因：' . $rs['msg'],
                    'code' => 11007
                ]);
            }
        } else {
            $step = 1;
            $tpl = '../index/add';
            if (!empty(self::$column)) {
                if ($id) {
                    $step = 3;
                    $rs = $this->query(['id' => $id, 'where' => '']);
                    $rs = $this->_init_data($rs);
                    $this->assign('rs', $rs);
                } else {
                    $step = 2;
                    $before = $this->before_add();
                    if (!empty($before)) $this->error($before['msg']);
                    $this->assign('upload_limit', (self::$column['setting']['group'][self::$user['group_id']]['upload_limit'] ?? 3));
                    $this->assign('pay', [
                        'add_money' => (self::$column['setting']['group'][self::$user['group_id']]['add_money'] ?? 0),
                        'add_credit' => (self::$column['setting']['group'][self::$user['group_id']]['add_credit'] ?? 0)
                    ]);
                    $this->assign('fields', load_fields(self::$column['id'], 0, '', 1));
                    $this->assign('post_phone_pc', (empty(self::$column['setting']['check']['post_phone_pc']) && empty(self::$cim['post_phone_pc'])) ? 0 : 1);
                    if (!empty(self::$column['setting']['template']['add'])) $tpl = '../add/' . self::$column['setting']['template']['add'];
                }
            }
            return view($tpl, [
                'step' => $step,
                'columns' => action('api/columns', ['use' => 'form', 'return' => 0]),
                'areas' => \load_areas()
            ]);
        }
    }

    /**
     * 修改
     */
    public function edit($key = '', $id = 0)
    {
        if (empty(self::$column)) return $this->_404();
        $rs = $this->query([
            'key' => $key,
            'id' => $id,
            'where' => '',
        ]);
        if (empty($rs)) return $this->_404();
        if (!action('index/api/check_owner', ['rs' => $rs])) return $this->redirect(url('index/index/manage', ['key'=>$key, 'id'=>$id]));
        $tpl = '../index/edit';
        if (!empty(self::$column['setting']['template']['add'])) $tpl = '../index/edit/' . self::$column['setting']['template']['add'];
        $this->assign('upload_limit', (self::$column['setting']['group'][self::$user['group_id']]['upload_limit'] ?? 3));
        $this->assign('fields', load_fields(self::$column['id'], 0, '', 1));
        if (!empty($rs['value'])) $rs['value'] = array_column($rs['value']->toArray(), null, 'fields_id');
        if (!empty($rs['fields'])) $rs['fields'] = (array)$rs['fields'];
        $rs->url = url('index/index/view', ['key'=>$key, 'id'=>$id]);
        return view($tpl, [
            'rs' => $rs,
            'column' => self::$column,
            'area_tree' => \load_areas(),
        ]);
    }

    /**
     * 空方法解析
     */
    public function _empty($name)
    {
        //数据操作 管理 置顶 红包 评论
        if (in_array($name, ['top', 'redpack', 'comment'])) {
            $rs = $this->query([
                'id' => input('param.id', 0),
                'where' => '',
                'cache' => 0
            ]);
            if (empty($rs)) return $this->_404();
            self::$column = load_column($rs['column_id']);
            if ($name == 'top') {
                $this->assign('pay', [
                    'money' => self::$column['setting']['group'][self::$user['group_id']]['top_money'] ?? 0,
                    'credit' => self::$column['setting']['group'][self::$user['group_id']]['top_credit'] ?? 0,
                ]);
            }
            return view('../index/' . $name, [
                'rs' => $this->_init_data($rs),
                'column' => self::$column
            ]);
        }
        //检测模板
        if (template_exists($name)) return view(template_exists($name));
        if (template_exists('index/' . $name)) return view(template_exists('index/' . $name));
        return $this->_404();
    }

    /**
     * 筛选项
     */
    private function filters($type = 'lists')
    {
        $orders = ['list' => ['最新信息', '热门信息', '红包信息'], 'fields' => ['create_time desc', 'hits desc', ['behavior', 'update_time']], 'order' => ['desc', 'desc', ['desc', 'desc']]];
        $areas = load_areas();
        $ops = [];
        $where = [];
        $order = '';
        $field = '';
        $params = input('param.');
        $selected = [];
        if (!empty(self::$column)) {
            $fields = load_fields(self::$column['id']);
            $url = self::$sys['module'] . '/' . self::$sys['controller'] . '/' . self::$sys['action'];
            foreach ($fields as $k => $v) {
                if (!empty($v['orders'])) {
                    $orders['list'][] = $v['name'];
                    $orders['fields'][] = $v['key'];
                    $orders['order'][] = $v['orders'] == 1 ? 'asc' : 'desc';
                    $field .= ",json_extract(fields,'$." . $v['key'] . "') " . $v['key'];
                }
                switch ($v['search']) {
                    //关键词搜索
                    case '1':
                        if (isset($params[$v['key']])) {
                            $fields[$k]['where'][] = $params[$v['key']];
                            $where[] = ['fields->' . $v['key'], 'like', '%' . $fields[$k]['where'][0] . '%'];
                            $selected[] = [
                                'name' => $v['name'],
                                'url' => url($url, array_merge(input('param.'), [$v['key'] => '', 'page' => ''])),
                                'value' => $params[$v['key']]
                            ];
                        }
                        if (!empty($v['search_item'])) {
                            $options = [];
                            foreach ($v['search_item'] as $sk => $sv) $options[$sv] = $sv;
                            $fields[$k]['filter'] = $this->init_filters([[$v['key'], $v['name'], $options]]);
                        }
                        break;
                    //范围搜索
                    case '2':
                        if (isset($params[$v['key']])) {
                            $fields[$k]['where'] = explode('_', $params[$v['key']]);
                            if (is_numeric($fields[$k]['where'][0])) {
                                $where[] = ['id', 'in', function ($query) use ($fields, $k) {
                                    $query->name('data')->field('id')->where('CONVERT(json_extract(`fields`, \'$.' . $fields[$k]['key'] . '\'),SIGNED) >=' . $fields[$k]['where'][0]);
                                }];
                            } else {
                                $fields[$k]['where'][0] = 0;
                            }
                            if (is_numeric($fields[$k]['where'][1])) {
                                $where[] = ['id', 'in', function ($query) use ($fields, $k) {
                                    $query->name('data')->field('id')->where('CONVERT(json_extract(`fields`, \'$.' . $fields[$k]['key'] . '\'),SIGNED) <=' . $fields[$k]['where'][1]);
                                }];
                            } else {
                                $fields[$k]['where'][1] = '*';
                            }
                            $selected[] = [
                                'name' => $v['name'],
                                'url' => url($url, array_merge(input('param.'), [$v['key'] => '', 'page' => ''])),
                                'value' => implode('-', $fields[$k]['where'])
                            ];
                        }
                        if (!empty($v['search_item'])) {
                            $options = [];
                            foreach ($v['search_item'] as $sk => $sv) $options[implode('_', $sv)] = implode('-', $sv) . $v['unit'];
                            $fields[$k]['filter'] = $this->init_filters([[$v['key'], $v['name'], $options]]);
                        }
                        break;
                    //列表搜索
                    case '3':
                        if (isset($params[$v['key']])) {
                            $where[] = ['fields->' . $v['key'], '=', $params[$v['key']]];
                        }
                        if (!empty($v['options'])) {
                            $options = [];
                            foreach ($v['options'] as $ok => $ov) {
                                $options[$ov['key']] = $ov['value'];
                            }
                            $ops[$v['key']] = [$v['key'], $v['name'], $options];
                        }
                        unset($fields[$k]);
                        break;
                    //多选搜索
                    case '4':
                        if (isset($params[$v['key']])) {
                            $fields[$k]['where'] = array_flip(explode('_', $params[$v['key']]));
                            $where[] = ['fields->' . $v['key'], 'like', explode(',', '%' . join('%,%', (array)get_array_keys(array_combine(array_column($v['options'], 'key'), array_column($v['options'], 'value')), array_keys($fields[$k]['where']))) . '%')];
                            $selected[] = [
                                'name' => $v['name'],
                                'url' => url($url, array_merge(input('param.'), [$v['key'] => '', 'page' => ''])),
                                'value' => implode(',', (array)get_array_keys(array_combine(array_column($v['options'], 'key'), array_column($v['options'], 'value')), array_keys($fields[$k]['where'])))
                            ];
                        }
                        break;
                }
            }
            $this->assign('search_fields', $fields);
        }
        if (!empty($areas)) {
            $ops['area'] = ['area', '区域', $areas];
            if (isset($areas[self::$area['id']]['child'])) {
                $ops['area'] = ['area', $areas[self::$area['id']]['name'], $areas[self::$area['id']]['child']];
            }
            if (self::$area['parent_id'] > 0) {
                $ops['area'] = ['area', $areas[self::$area['parent_id']]['name'], $areas[self::$area['parent_id']]['child']];
            }
            if (isset($params['area'])) {
                $areas = load_areas(1);
                if (!empty($areas[$params['area']]['child'])) {
                    $area_ids = array_merge([$params['area']], array_keys($areas[$params['area']]['child']));
                    $where[] = ['area_id', 'in', $area_ids];
                } else {
                    $where[] = ['area_id', '=', $params['area']];
                }
            }
        }
        $ops['order'] = ['orders', '排序', $orders['list']];
        $filters = [
            $type => $this->init_filters($ops),
        ];
        if (isset($params['orders']) && isset($orders['fields'][$params['orders']])) {
            if (is_array($orders['fields'][$params['orders']])) {
                $order = '';
                foreach ($orders['fields'][$params['orders']] as $k => $v) {
                    $order .= $v . ' ' . $orders['order'][$params['orders']][$k] . ',';
                }
                $order = trim($order, ',');
            } else {
                $order = $orders['fields'][$params['orders']] . ' ' . $orders['order'][$params['orders']];
            }
        }
        $filters['lists']['selected'] = isset($filters['lists']['selected']) ? array_merge($filters['lists']['selected'], $selected) : $selected;
        $this->assign('filters', $filters);
        return ['where' => $where, 'order' => $order, 'fields' => rtrim($field, ',')];
    }

    /**
     * 解析模板
     */
    private function _template($type, $column = [])
    {
        if (!empty(self::$column['setting']['template'][$type])) return '../' . $type . '/' . self::$column['setting']['template'][$type];
        return '../' . $type . '/' . self::$column['model'];
    }

}
