<?php
namespace Manage\Src;

use Dever;
use Dever\Http\Api as Base;

class Api
{
    /**
     * fast
     *
     * @var array
     */
    private $fast = array();

    /**
     * data
     *
     * @var array
     */
    private $data = array();

    /**
     * 启动tcp服务
     *
     * @return array
     */
    public function tcp()
    {
        //return Dever::tcpReload(30000);
    }

    /**
     * 测试dyna配置
     *
     * @return array
     */
    public function dyna()
    {
        $data['name'] = 1;
        $data = Dever::dyna('home', $data);
        return $data;
    }

    /**
     * 测试传统模板引擎（类似smarty）
     *
     * @return array
     */
    public function test_display_api()
    {
        $data['test'] = 1111111111111;
        $data['data'] = $this->test_foreach();
        return Dever::render('example/render', $data);
    }

    public function test_display_data()
    {
        return 12323234;
    }

    public function test_foreach()
    {
        $config = array
            (
            array
            (
                'id' => 1,
                'name' => '1111',
                'child' => array
                (
                    array
                    (
                        'id' => 3,
                        'name' => '3333',
                        'child' => array
                        (
                            array
                            (
                                'id' => 9,
                                'name' => '9999',
                            ),
                            array
                            (
                                'id' => 10,
                                'name' => '10101010',
                            ),
                        ),
                    ),
                    array
                    (
                        'id' => 4,
                        'name' => '4444',
                    ),
                ),
            ),
            array
            (
                'id' => 2,
                'name' => '2222',
                'child' => array
                (
                    array
                    (
                        'id' => 5,
                        'name' => '5555',
                    ),
                    array
                    (
                        'id' => 6,
                        'name' => '6666',
                    ),
                ),
            ),
        );

        return $config;
    }

    /**
     * 测试接口定义
     *
     * @return array
     */
    public function test_api()
    {
        $data = Dever::load('module/data.test');

        print_r($data);die;
    }

    /**
     * 测试逻辑验证步骤，必须包含step
     *
     * @return array
     */
    public function test_step_1()
    {
        print_r(Dever::input('type'));
        # 传给下一步的数据
        Dever::setStep('test');

        $url = Dever::url('api.test_step_2?' . http_build_query(Dever::$global['step'][1]));

        print_r($url);die;

        #ok

        echo 11;die;
    }

    /**
     * 测试逻辑验证步骤，必须包含step
     *
     * @return array
     */
    public function test_step_2()
    {
        $data = Dever::getStep();
        print_r($data);die;
        echo 22;die;
    }

    /**
     * 从数据库中得到所有接口，如果为空，则从项目中读取一次
     *
     * @return array
     */
    private function get($auth = '')
    {
        $data = Dever::load('manage/api-all');

        if ($data) {
            foreach ($data as $k => $v) {

            }
        } else {
            # 数据为空，读取一次，后续就得手动读取了
            $this->load();

            $data = $this->get();
        }

        return $data;
    }

    /**
     * 更新接口
     *
     * @return array
     */
    public function update_api()
    {
        $this->load();

        Dever::out('yes');
    }

    /**
     * 载入从项目中定义好的接口
     *
     * @return array
     */
    public function load()
    {
        $project = Dever::load('manage/project.get');

        foreach ($project as $k => $v) {
            $data = Base::config($v['path']);

            if ($data) {
                foreach ($data as $i => $j) {
                    $j['order'] = isset($j['order']) ? $j['order'] : 1;

                    $this->updateApi($i, $j['name'], $j['type'], $k, $j['request'], $j['response'], $j['order']);
                }
            }
        }
    }

    private function updateApi($site, $name, $type, $project, $request, $response, $reorder, $state = true)
    {
        $info = Dever::db('manage/api')->site(array('where_site' => $site));
        if (!$info) {
            $update['add_site'] = $site;
            $update['add_name'] = $name;
            $update['add_type'] = $type;
            $update['add_project'] = $project;
            $update['add_reorder'] = $reorder;
            $info['id'] = Dever::db('manage/api')->insert($update);
        } elseif ($state) {
            $update['set_site'] = $site;
            $update['set_name'] = $name;
            $update['set_type'] = $type;
            $update['set_project'] = $project;
            $update['set_reorder'] = $reorder;
            $update['where_id'] = $info['id'];
            Dever::db('manage/api')->update($update);
        }

        if ($info['id'] > 0) {
            $this->updateApiData(array($response, $request), $info['id']);
        }

        return true;
    }

    private function updateApiData($data, $id)
    {
        $this->api_response = $this->api_request = array();
        foreach($data as $k => $v) {
            if ($v && is_array($v)) {
                if ($k == 0) {
                    $api = 'api_response';
                } else {
                    $api = 'api_request';
                }
                $this->insertApiData($api, $v, $id, -1, 0);
            }
        }
    }

    private function insertApiData($api, $data, $aid, $id = -1, $num = 0)
    {
        foreach($data as $k => $v) {
            $value = $v;
            if (is_array($value)) {
                $value = 'array:' . $k;
                if (isset($v[0][0])) {
                    $v = $v[0][0];
                }
                if (isset($v[0])) {
                    $v = $v[0];
                }
            }

            if (isset($this->{$api}[$num][$k])) {
                //continue;
            }
            $this->{$api}[$num][$k] = $value;

            $insertId = $this->insertApiDataOne($api, $k, $value, $aid, $id);
            if ($insertId > 0 && is_array($v)) {
                
                $this->insertApiData($api, $v, $aid, $insertId, $num+1);
            }
        }
    }

    private function insertApiDataOne($api, $name, $data, $aid, $id = -1)
    {
        if (is_array($data)) {
            $type = $data[0];
            $desc = $data[1];
        } else {
            $type = 'string';
            if (is_numeric($name)) {
                $type = 'int';
            } elseif (strpos($name, 'id') !== false) {
                $type = 'int';
            }

            $desc = $data;
        }

        if (strlen($desc) > 100) {
            $desc = '{long}';
        }
        $update['add_api_id'] = $aid;
        $update['add_name'] = $name;
        $update['add_type'] = $type;
        $update['add_desc'] = $desc;
        $update['add_parent_id'] = $id;
        $update['add_desc'] = $desc;
        $one = array
        (
            'option_parent_id' => $id,
            'option_api_id' => $aid,
            'option_name' => $name,
        );
        $info = Dever::db('manage/' . $api)->one($one);
        if (!$info) {
            return Dever::db('manage/' . $api)->insert($update);
        }
        return $info['id'];
    }

    public function showTable($data, $url = '', $api = '')
    {
        $result = '<table border=1 width=100% height=100%>';
        if ($data) {
            $result .= Dever::tbody(array('字段', '类型', '描述'));
            $num = count($data);
            $table = array();
            foreach ($data as $k => $v) {
                if ($v['name'] == '{struct}') {
                    $table[$k] = '';
                    unset($data[$k]);
                    $struct = Dever::db($k)->config['struct'];
                    if ($v['desc']) {
                        $temp = $v['desc'];
                    } else {
                        $temp = $struct;
                    }

                    if ($temp) {
                        foreach ($temp as $i) {
                            if (isset($struct[$i]) && isset($struct[$i]['type'])) {
                                $type = explode('-', $struct[$i]['type']);
                                $table[$k] .= Dever::tbody(array($i, $type[0], $struct[$i]['name']));
                            }
                        }

                        if ($v['type']) {
                            $data[$v['type']] = array('array/json', $result . $table[$k] . '</table>');
                        } else {
                            $result .= $table[$k];
                        }
                    }
                }
            }
        } else {
            $result .= '空';
        }

        $this->table($data, $result, $url, $api);

        return $result;
    }

    private function table($data, &$table, $url = '', $api = '')
    {
        if ($data && is_array($data)) {
            foreach ($data as $k => $v) {
                if (is_array($v['desc'])) {
                    $tbody = '<table border=1 width=100% height=100%>';
                    $this->table($v['desc'], $tbody) . '</table>';
                    $v['desc'] = $tbody;
                }

                $v['name'] = '<span class="edit" data-col="name" data-url="'.$url.'" data-id="'.$v['id'].'" data-type="'.$api.'" >' . $v['name'] . '</span>';

                $v['type'] = '<span class="edit" data-col="type" data-url="'.$url.'" data-id="'.$v['id'].'" data-type="'.$api.'" >' . $v['type'] . '</span>';

                $v['desc'] = '<span class="edit" data-col="desc" data-url="'.$url.'" data-id="'.$v['id'].'" data-type="'.$api.'" >' . $v['desc'] . '</span>';

                $table .= Dever::tbody(array($v['name'], $v['type'], $v['desc']));
            }
        }

        $table .= '</table>';
    }

    public function push($param = false)
    {
        $param = $param ? $param : json_decode(base64_decode(Dever::input('param')), true);
        $api = explode('_api', $param['api']);
        $api = $api[0];
        $temp = explode('/', $api);
        $project = $temp[0];
        unset($temp[0]);
        $site = implode('/', $temp);

        $request = array();
        foreach ($param['request'] as $k => $v) {
            if (!strpos($k, '/') && !strpos($k, '?') && $k != 'json' && $k != 'callback') {
                $request[$k] = $v;
            }
        }

        $type = 1;
        $this->updateApi($site, $api, $type, $project, $request, $param['response'], 1, false);
    }

    public function update_col_api()
    {
        $table = Dever::input('type');
        $col = Dever::input('col');
        $id = Dever::input('id');
        $value = Dever::input('value');
        $update['set_' . $col] = $value;
        $update['where_id'] = $id;
        Dever::db('manage/' . $table)->update($update);
    }


    public function getHtml($name, $site, $html, $id, $project)
    {
        $one = array
        (
            'option_api_id' => $id,
        );
        $request = Dever::db('manage/api_request')->all($one);
        $response = Dever::db('manage/api_response')->all($one);

        $request = $this->showTable($request);
        $response = $this->showTable($response);
        return '接口名称：'.$name.'<br />接口地址：<br  />'.Dever::url($site, $project).'<br />'.$html.'请求参数：<br />'.$request.'<br />输出参数：<br />'.$response;
    }
}
