<?php

namespace app\api\controller;

use addons\shopro\model\Config;
use app\common\exception\UploadException;
use app\common\library\Upload;
use Qiniu\Auth;
use Qiniu\Storage\ResumeUploader;
use Qiniu\Storage\UploadManager;
use think\Db;
use think\Config as FaConfig;
use fast\Random;
use app\api\model\Banner;
use addons\shopro\model\Category;

/**
 * 首页接口
 */
class Index extends Base
{

    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];

    /**
     * @ApiWeigh    (99)
     * @ApiTitle    (首页)
     * @ApiSummary  (首页)
     * @ApiMethod   (GET)
     *
     * @ApiHeaders (name=token, type=string, required=false, description="请求的token")
     *
     * @ApiReturn({
        "code": 1,
        "msg": "首页",
        "time": "1608036399",
        "data": {
            "banner_list": [{ //轮播图
                "id": 3, //轮播图ID
                "image": "http://www.ant.top/uploads/20201214/b655ea4dc4779222ab7a4e2b95feb3a4.png" //图片地址
                "type" : '1', //跳转类型:1=无跳转,2=商品,3=开通会员
                "goods_id" : 1, //商品ID
            }],
            "category_list": [{ //一级分类
                "id": 1, //分类ID
                "name": "商品分类", //分类名称
                "image": "http://www.ant.top/uploads/20201221/559d2a240ec20b096590a902217009ff.png", //分类图片
            }],
            "seckill_list": {
                "type": "ing", // 类型:ing=进行中,nostart=即将开始,tomorrow=明日预告
                "current_endtime": { //距离本场结束
                    "hour": 10,
                    "minute": 12,
                    "second": 19
                },
                "soon_starttime": { //即将开始时间
                    "hour": 14,
                    "minute": 00
                },
                "goodsList": [{
                    "id": 1, //商品ID
                    "type": "normal",
                    "title": "测试商品", //标题
                    "subtitle": "测试啊", //副标题
                    "weigh": 0,
                    "category_ids": "3", //所属分类ID
                    "image": "http://www.ant.top/assets/img/qrcode.png", //商品主图
                    "price": "0.01", //商品价格
                    "original_price": "10000.00", //原价
                    "is_sku": 0,
                    "likes": 0,
                    "views": 3,
                    "sales": 0, //销量
                    "show_sales": 0, //显示销量
                    "dispatch_type": "express",
                    "dispatch_ids": "1",
                    "deletetime": null,
                    "activity": {
                        "id": 7,
                        "title": "秒杀测试",
                        "type": "seckill",
                        "richtext_id": 0,
                        "richtext_title": "",
                        "starttime": 1607616000,
                        "endtime": 1607702400,
                        "rules": {
                            "limit_buy": "1",
                            "order_auto_close": "",
                            "activity_auto_close": ""
                        }
                    },
                    "activity_type": "seckill",
                    "sku_price": [{
                        "id": 1,
                        "goods_sku_ids": null,
                        "goods_id": 1,
                        "weigh": 0,
                        "image": null,
                        "stock": 20,
                        "sales": 0,
                        "sn": "",
                        "weight": 0,
                        "price": "0.01",
                        "goods_sku_text": null,
                        "status": "up",
                        "activity_type": "seckill",
                        "activity_id": 7,
                        "item_goods_sku_price": {
                        "id": 4,
                        "activity_id": 7,
                        "sku_price_id": 1,
                        "goods_id": 1,
                        "stock": 20,
                        "sales": 0,
                        "price": "0.01",
                        "status": "up"
                        },
                        "goods_sku_id_arr": [
                        ""
                        ]
                    }],
                    "stock": 20,
                    "dispatch_type_arr": [
                        "express"
                    ]
                }]
            },
            "groupon_list": {
                "type": "ing", // 类型:ing=进行中,nostart=即将开始,tomorrow=明日预告
                "current_endtime": {
                    "hour": 10,
                    "minute": 12,
                    "second": 19
                },
                "soon_starttime": { //即将开始时间
                    "hour": 14,
                    "minute": 00
                },
                "goodsList":[{
                    "id": 2, //商品ID
                    "type": "normal",
                    "title": "测试商品2", //商品标题
                    "subtitle": "测试啊啊", //商品副标题
                    "weigh": 0,
                    "category_ids": "3",
                    "image": "http://www.ant.top/uploads/20201211/8894d62100f2f920ffb2f38063b63f2d.jpg", //商品主图
                    "price": "0.02", //现价
                    "original_price": "1000.00", //原价
                    "is_sku": 0, //是否多规格:0=否,1=是
                    "likes": 0,
                    "views": 1,
                    "sales": 0,
                    "show_sales": 0, //显示销量
                    "dispatch_type": "express",
                    "dispatch_ids": "1",
                    "deletetime": null,
                    "activity": {
                        "id": 9, //活动ID
                        "title": "拼团测试", //活动标题
                        "type": "groupon", //活动类型:seckill=秒杀,groupon=拼团
                        "richtext_id": 0,
                        "richtext_title": "",
                        "starttime": 1607616000,
                        "endtime": 1607702400,
                        "rules": { //活动规则
                            "limit_buy": "1", //每人限购件数
                            "order_auto_close": "",
                            "activity_auto_close": "",
                            "team_num": "2", //成团人数
                            "is_alone": "0", //是否允许单独购买
                            "is_fictitious": "0",
                            "fictitious_num": "",
                            "valid_time": "",
                            "team_card": "0"
                        }
                    },
                    "activity_type": "groupon",
                    "groupon_price": "0.01",
                    "sku_price": [{
                        "id": 2,
                        "goods_sku_ids": null,
                        "goods_id": 2,
                        "weigh": 0,
                        "image": null,
                        "stock": 10,
                        "sales": 0,
                        "sn": "",
                        "weight": 0,
                        "price": "0.02",
                        "goods_sku_text": null,
                        "status": "up",
                        "groupon_price": "0.01",
                        "activity_type": "groupon",
                        "activity_id": 9,
                        "item_goods_sku_price": {
                            "id": 5,
                            "activity_id": 9,
                            "sku_price_id": 2,
                            "goods_id": 2,
                            "stock": 10,
                            "sales": 0,
                            "price": "0.01",
                            "status": "up"
                        },
                        "goods_sku_id_arr": [
                            ""
                        ]
                    }],
                    "stock": 10,
                    "dispatch_type_arr": [
                    "express"
                    ]
                }]
            }
        }
    })
     */
    public function index()
    {
        $banner_list = Banner::field('id,image,type,goods_id')->select();
        $category_list = Category::where('pid',1)->field('id,name,image')->limit(9)->select();
        $seckill_list = \addons\shopro\model\Goods::indexActivityGoodsList('seckill');
        $groupon_list = \addons\shopro\model\Goods::indexActivityGoodsList('groupon');
        $this->success('首页', compact('banner_list','category_list','seckill_list','groupon_list'));
    }

    /**
     * @ApiWeigh    (97)
     * @ApiTitle    (分享标题和图片)
     * @ApiSummary  (分享标题和图片)
     * @ApiMethod   (GET)
     *
     * @ApiReturn({
        "code": 1,
        "msg": "首页",
        "time": "1610097015",
        "data": {
            "title": "邀请有好礼", //分享标题
            "image": "http://api.7wpp.com/uploads/20200414/4be7c944935a0fd6fc890f0214e6c3e0.jpg" //分享图片
        }
    })
     */
    public function share()
    {
        $share = json_decode(Config::where(['name' => 'share'])->value('value'), true);
        $this->success('首页', [
            'title' => $share['title'],
            'image' => isset($share['image']) ? cdnurl($share['image'], true) : '',
        ]);
    }

    /**
     * @ApiInternal
     * 初始化商城数据
     */
    public function init()
    {
        $params = $this->request->get();
        $platform = $this->request->header('platform');

        $config = new \addons\shopro\model\Config;

        $platformConfig = json_decode($config->where(['name' => $platform])->value('value'), true);
        $paymentConfig = $config->where('group', 'payment')->select();
        $payment = [];
        foreach ($paymentConfig as $key => $config) {
            $val = json_decode($config->value, true);
            if ($val && in_array($platform, $val['platform'])) {
                $payment[] = $config->name;
            }
        }
        $data['payment'] = $payment;        // 平台支持的支付方式

        $shopro = json_decode(Config::where(['name' => 'shopro'])->value('value'), true);
        $data['info'] = $shopro;
        $data['info']['logo'] = cdnurl($data['info']['logo'], true);
        $autologin = false;
        if (isset($platformConfig['auto_login']) && $platformConfig['auto_login'] == 1) {
            $autologin = true;
        }
        $data['wechat'] = [
            'appid' => isset($platformConfig['app_id']) ? $platformConfig['app_id'] : '',
            'autologin' => $autologin,
        ];
        $share = json_decode(Config::where(['name' => 'share'])->value('value'), true);

        $data['share'] = [
            'title' => $share['title'],
            'image' => isset($share['image']) ? cdnurl($share['image'], true) : '',
            'goods_poster_bg' => isset($share['goods_poster_bg']) ? cdnurl($share['goods_poster_bg'], true) : '',
            'user_poster_bg' => isset($share['user_poster_bg']) ? cdnurl($share['user_poster_bg'], true) : '',
            'groupon_poster_bg' => isset($share['groupon_poster_bg']) ? cdnurl($share['groupon_poster_bg'], true) : '',
        ];
        $data['addons'] = array_keys(get_addon_list());
        $this->success('初始化数据', $data);

    }

    /**
     * @ApiInternal
     * 商城模板数据
     */
    public function template()
    {
        $get = $this->request->get();
        $platform = $this->request->header('platform');
        if (isset($get['shop_id'])) {
            $template = \addons\shopro\model\Decorate::getCurrentPlatformDecorate('preview', $get['shop_id']);
        } else {
            $template = \addons\shopro\model\Decorate::getCurrentPlatformDecorate($platform);
        }
        $this->success('模板数据', $template);
    }

    /**
     * @ApiInternal
     * 自定义页面
     */
    public function custom()
    {
        $get = $this->request->get();
        $decorate = \addons\shopro\model\Decorate::get($get['id']);
        if (!$decorate) {
            $this->error('未找到自定义页面');
        }
        $decorate->template = \addons\shopro\model\Decorate::getCustomDecorate($get['id']);
        $this->success('自定义模板数据', $decorate);
    }

    /**
     * @ApiInternal
     * 富文本详情
     */
    public function richtext()
    {
        $id = $this->request->get('id');
        $data = \addons\shopro\model\Richtext::get(['id' => $id]);
        $this->success($data->title, $data);
    }

    /**
     * @ApiInternal
     * 同步前端所有页面链接
     */
    public function asyncLink()
    {
        $post = $this->request->post();
        $newLink = $post['data'];
        $existLink = Db::name('shopro_link')->select();
        $newLinkPath = array_column($newLink, 'path');
        $existLinkPath = array_flip(array_column($existLink, 'path'));
        $insertData = [];
        $count = 1;
        foreach ($newLinkPath as $key => $item) {
            if (!isset($existLinkPath[$item]) && isset($newLink[$key]['meta']['async']) && $newLink[$key]['meta']['async']) {
                $insertData[] = [
                    'name' => isset($newLink[$key]['meta']['title']) ? $newLink[$key]['meta']['title'] : '新链接' . $count,
                    'path' => $item,
                    'group' => isset($newLink[$key]['meta']['group']) ? $newLink[$key]['meta']['group'] : '其它',
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                $count++;
            }
        }
        if ($insertData !== []) {
            Db::name('shopro_link')->insertAll($insertData);
        }
    }

    /**
     * @ApiInternal
     * 前端获取轮播图平均色
     * 1.0.7以后此接口作废
     */
    public function asyncBannerBgColor()
    {
        $params = $this->request->post();
        $platform = $this->request->header('platform');
        $data['template'] = \addons\shopro\model\Decorate::asyncBannerBgColor($platform, $params);
    }

    /**
     * @ApiInternal
     * 店铺装修 截图商城首页
     */
    public function asyncDecorateScreenShot()
    {
        $params = $this->request->post();
        \addons\shopro\model\Decorate::asyncDecorateScreenShot($params);
    }

    /**
     * 中转上传文件
     * 上传分片
     * 合并分片
     * @ApiMethod (POST)
     * @param File $file 文件流
     */
    public function upload()
    {
        FaConfig::set('default_return_type', 'json');

//        $this->check();
        $config = get_addon_config('qiniu');
        $config['savekey'] = str_replace(['{year}', '{mon}', '{day}', '{filemd5}', '{.suffix}'], ['$(year)', '$(mon)', '$(day)', '$(etag)', '$(ext)'], $config['savekey']);

        // 构建鉴权对象
        $auth = new Auth($config['accessKey'], $config['secretKey']);
        // 生成上传 Token
        $token = $auth->uploadToken($config['bucket'], null, 3600, ['saveKey' => ltrim($config['savekey'], '/')]);
        // 初始化 UploadManager 对象并进行文件的上传。
        $uploadMgr = new UploadManager();

        $chunkid = $this->request->post("chunkid");
        if ($chunkid) {
            $action = $this->request->post("action");
            $chunkindex = $this->request->post("chunkindex/d");
            $chunkcount = $this->request->post("chunkcount/d");
            $filesize = $this->request->post("filesize");
            $filename = $this->request->post("filename");
            if ($action == 'merge') {
                if ($config['uploadmode'] == 'server') {
                    $attachment = null;
                    //合并分片文件
                    try {
                        $upload = new Upload();
                        $attachment = $upload->merge($chunkid, $chunkcount, $filename);
                    } catch (UploadException $e) {
                        $this->error($e->getMessage());
                    }
                }

                $contexts = $this->request->post("contexts/a", []);
                $uploader = new ResumeUploader($token, null, null, $filesize);
                list($ret, $err) = $uploader->setContexts($contexts)->makeFile($filename);
                if ($err !== null) {
                    $this->error("上传失败");
                } else {
                    $this->success("上传成功", '', ['url' => '/' . $ret['key'], 'fullurl' => cdnurl('/' . $ret['key'], true), 'hash' => $ret['hash']]);
                }
            } else {
                //默认普通上传文件
                $file = $this->request->file('file');
                try {
                    $upload = new Upload($file);
                    $file = $upload->chunk($chunkid, $chunkindex, $chunkcount);
                } catch (UploadException $e) {
                    $this->error($e->getMessage());
                }

                //上传分片文件
                //$file = $this->request->file('file');
                $filesize = $file->getSize();
                //合并分片文件
                $uploader = new ResumeUploader($token, null, fopen($file->getRealPath(), 'rb'), $filesize);
                $ret = $uploader->uploadChunk($chunkindex, $file, $filesize);
                $this->success("上传成功", "", $ret);
            }
        } else {
            $attachment = null;
            //默认普通上传文件
            $file = $this->request->file('file');
            try {
                $upload = new Upload($file);

                $suffix = $upload->getSuffix();
                $md5 = md5_file($file->getRealPath());
                $search = ['$(year)', '$(mon)', '$(day)', '$(etag)', '$(ext)'];
                $replace = [date("Y"), date("m"), date("d"), $md5, '.' . $suffix];
                $savekey = ltrim(str_replace($search, $replace, $config['savekey']), '/');

                $attachment = $upload->upload($savekey);
            } catch (UploadException $e) {
                $this->error($e->getMessage());
            }

            //文件绝对路径
            $filePath = $upload->getFile()->getRealPath() ?: $upload->getFile()->getPathname();

            //上传到七牛后保存的文件名
            $saveKey = ltrim($attachment->url, '/');

            try {
                // 调用 UploadManager 的 putFile 方法进行文件的上传。
                list($ret, $err) = $uploadMgr->putFile($token, $saveKey, $filePath);

                if ($err !== null) {
                    throw new \Exception("上传失败");
                }
                //成功不做任何操作
            } catch (\Exception $e) {
                $attachment->delete();
                @unlink($filePath);
                $this->error("上传失败");
            }

            $this->success("上传成功", ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
        }
    }


    /**
     * 上传 base64 图片
     * @ApiMethod (POST)
     * @param base64 内容
     */
    public function uploadBase64()
    {
        $content = $this->request->post('content', '');
        
        if (empty($content) || !preg_match('/^(data:\s*image\/(\w+);base64,)/', $content, $matches)) {
            $this->error(__('No file upload or server upload limit exceeded'));
        }
        
        $upload = FaConfig::get('upload');

        $suffix = $matches[2]; //图片后缀

        $mimetypeArr = explode(',', strtolower($upload['mimetype']));

        // 判断是否允许的后缀
        if ($upload['mimetype'] !== '*' && !in_array($suffix, $mimetypeArr)) {
            $this->error(__('Uploaded file format is limited'));
        }

        $replaceArr = [
            '{year}' => date("Y"),
            '{mon}' => date("m"),
            '{day}' => date("d"),
            '{hour}' => date("H"),
            '{min}' => date("i"),
            '{sec}' => date("s"),
            '{random}' => Random::alnum(16),
            '{random32}' => Random::alnum(32),
            '{filename}' => "店铺装修截图",
            '{suffix}' => $suffix,
            '{.suffix}' => $suffix ? '.' . $suffix : '',
            '{filemd5}' => md5($content),
        ];
        $savekey = $upload['savekey'];
        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);

        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
        $fileName = substr($savekey, strripos($savekey, '/') + 1);
        $fullDir = ROOT_PATH . '/public' . $uploadDir;

        $uploadPath = $uploadDir . $fileName;
        $fullPath = $fullDir . $fileName;

        if (!is_dir($fullDir)) {
            mkdir($fullDir, 0777, true);
        }

        $imageContent = base64_decode(str_replace($matches[1], '', $content));
        if (file_put_contents($fullPath, $imageContent)) {
            $imgInfo = getimagesize($fullPath);

            $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : 0;
            $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : 0;

            $params = array(
                'admin_id' => 0,
                'user_id' => (int) $this->auth->id,
                'filesize' => strlen($content),
                'imagewidth' => $imagewidth,
                'imageheight' => $imageheight,
                'imagetype' => $suffix,
                'imageframes' => 0,
                'mimetype' => isset($imgInfo['mime']) ? $imgInfo['mime'] : 'image/' . $suffix,
                'url' => $uploadPath,
                'uploadtime' => time(),
                'storage' => 'local',
                'sha1' => hash_file('sha1', $fullPath),
            );
            $attachment = new \app\common\model\Attachment;
            $attachment->data(array_filter($params));
            $attachment->save();

            \think\Hook::listen("upload_after", $attachment);
            $this->success(__('Upload successful'), [
                'url' => $uploadPath,
                'full_url' => request()->domain() . $uploadPath
            ]);
        } else {
            $this->error("文件上传失败");
        }
    }

    /**
     * @ApiInternal
     * 写调试日志
     */
    public function debugLog()
    {
        $params = $this->request->post();
        \think\Log::write($params, 'notice');
    }

}