<?php

namespace app\controller\api\dataview;

use app\common\model\store\order\StoreOrder;
use app\common\model\user\UserVisit;
use app\common\repositories\BaseRepository;
use app\common\repositories\store\order\StoreOrderRepository;
use app\common\repositories\user\UserRepository;
use app\common\repositories\user\UserVisitRepository;
use crmeb\basic\BaseController;
use think\App;
use think\facade\Cache;
use think\facade\Db;
use think\exception\ValidateException;

class User extends BaseController
{
    /**
     * @var repository
     */
    protected $repository;

    public $areaCode; // 区县地区码

    public $streetCode; // 镇街道地区码

    public function __construct(App $app, BaseRepository $repository)
    {
        parent::__construct($app);
        $this->repository = $repository;
        $this->areaCode = $this->request->param('areaCode', '');
        $this->streetCode = $this->request->param('streetCode', '');

        if ($this->areaCode == '' && $this->streetCode == '') {
            throw  new ValidateException('请选择地区');
        }
    }

    public function userMerchantCount()
    {
        // 近5日 平台用户量统计
        $userCountlist = [];
        $merchatCountList = [];
        // 4天前
        $startBeforeDay5 = strtotime(date('Y-m-d', strtotime('-4 days')));
        $endBeforeDay5  = $startBeforeDay5+ 86399;
        $userCountlist[] = $this->getTimeRangeUserCount([$startBeforeDay5, $endBeforeDay5]);

        // 3天前
        $startBeforeDay4 = strtotime(date('Y-m-d', strtotime('-3 days')));
        $endBeforeDay4 = $startBeforeDay4 + 86399;
        $userCountlist[] = $this->getTimeRangeUserCount([$startBeforeDay4, $endBeforeDay4]);

        // 2天前
        $startBeforeDay3 = strtotime(date('Y-m-d', strtotime('-2 days')));
        $endBeforeDay3  = $startBeforeDay3 + 86399;
        $userCountlist[] = $this->getTimeRangeUserCount([$startBeforeDay3, $endBeforeDay3]);

        // 1天前
        $startBeforeDay2= strtotime(date('Y-m-d', strtotime('-1 days')));
        $endBeforeDay2  = $startBeforeDay2+ 86399;
        $userCountlist[] = $this->getTimeRangeUserCount([$startBeforeDay2, $endBeforeDay2]);

        // 今天
        $startCurrDay1 = strtotime(date('Y-m-d', time()));
        $endCurrDay1   = $startCurrDay1+ 86399;
        $userCountlist[] = $this->getTimeRangeUserCount([$startCurrDay1, $endCurrDay1]);

        // 地方店铺数量统计

        // 遍历统计每个乡镇的店铺数
        $merchantTotalCount = 0;

        // 查镇的用户统计不需要查店铺数
        if ($this->streetCode == '') {

            // 该地区下所有乡镇
            $geoStreetList =  Db::name('geo_street')->where('area_code',$this->areaCode)->select()->toArray();

            foreach ($geoStreetList as $street) {
                $temp['street_name'] = $street['street_name'];
                $temp['merchant_count'] = Db::name('merchant')->where('street_id', $street['street_code'])->count();
                $merchantTotalCount += $temp['merchant_count'];
                $merchatCountList[] = $temp;
                unset($temp);
            }
        }

        return app('json')->success(compact('merchantTotalCount' ,'userCountlist', 'merchatCountList'));
    }
    public function getTimeRangeUserCount($timeRange=[])
    {
        // 新增
        $newUserCount = Db::name('user')->alias('u')
            ->join('user_address ua', 'u.uid = ua.uid')
            ->where(function ($query){
                if ($this->streetCode != '') {
                    $query->where('ua.street', $this->streetCode);
                } else {
                    $query->where('ua.district', $this->areaCode);
                }
            })
            ->whereTime('u.create_time', 'between', $timeRange)
            ->count();

        // 访问
        $viewUserCount = Db::name('user')->alias('u')
            ->join('user_address ua', 'u.uid = ua.uid')
            ->where(function ($query){
                if ($this->streetCode != '') {
                    $query->where('ua.street', $this->streetCode);
                } else {
                    $query->where('ua.district', $this->areaCode);
                }
            })
            ->whereTime('u.last_time', 'between', $timeRange)
            ->count();

        // 累计
        $totalUserCount = Db::name('user')->alias('u')
            ->join('user_address ua', 'u.uid = ua.uid')
            ->where(function ($query){
                if ($this->streetCode != '') {
                    $query->where('ua.street', $this->streetCode);
                } else {
                    $query->where('ua.district', $this->areaCode);
                }
            })
            ->whereTime('u.create_time', '<', $timeRange[1])
            ->count();

        return compact('newUserCount', 'viewUserCount', 'totalUserCount');
    }

    public function userTradeCount(StoreOrderRepository $orderRepository, UserVisitRepository $userVisitRepository)
    {

        $monthDateRow = [];
        // 获取当前月份的第一天
        $firstDay = date('Y-m-01', time());
        $i = 0;
        $lastDay = date('Y-m-d', strtotime("$firstDay +1 month -1 day"));
        while (date('Y-m-d', strtotime("$firstDay +$i days")) <= $lastDay) {
            $monthDateRow[] = date('Y-m-d', strtotime("$firstDay +$i days"));
            $i++;
        }

        $this->merId = null;
        $userTradeCountList = Cache::store('file')->remember(self::class . '@userTradeCount' . $this->streetCode, function () use ($orderRepository, $userVisitRepository, $monthDateRow) {
            $list = [];
            foreach ($monthDateRow as $date) {
               $visitUser = $this->dateVisitUserNum($date);
               $orderUser = $this->orderUserNum($date, null);
//               $orderPrice = $this->orderPrice($date, null);
               $payOrderUser = $this->orderUserNum($date, 1);
               $payOrderPrice = $this->orderPrice($date, 1);
//               $userRate = $payOrderUser ? bcdiv($payOrderPrice, $payOrderUser, 2) : 0;
//               $orderRate = $visitUser ? bcdiv($orderUser, $visitUser, 2) : 0;
//               $payOrderRate = $orderUser ? bcdiv($payOrderUser, $orderUser, 2) : 0;
               $list[] = compact('date','visitUser', 'orderUser', 'payOrderUser');
           }
            return $list;
        }, 2000 + random_int(600, 1200));

        // 县
        $area = Db::name('geo_area')->field('area_code, area_name')->where('area_code', $this->areaCode)->find();
        // 镇/街道
        $streetList = Db::name('geo_street')->field('street_code, street_name')->where('area_code', $this->areaCode)->select();
        return app('json')->success(compact('userTradeCountList', 'area', 'streetList'));
    }

    protected function dateVisitUserNum($date)
    {
        return UserVisit::getDB()->alias('A')->join('StoreProduct B', 'A.type_id = B.product_id')->join('merchant m', 'B.mer_id=m.mer_id')->when($date, function ($query, $date) {
            getModelTime($query, $date, 'A.create_time');
        })->where( function ($query) {
            if ($this->streetCode != '') {
                $query->where('m.street_id', $this->streetCode);
            } else {
                $query->where('m.area_id', $this->areaCode);
            }
        })->where('A.type', 'product')->group(' A.uid')->count();
    }

    public function orderUserNum($date, $paid = null)
    {
        return StoreOrder::getDB()->alias('o')->join('merchant m', 'o.mer_id=m.mer_id')->when($paid, function ($query, $paid) {
            $query->where('paid', $paid);
        })->where( function ($query) {
            if ($this->streetCode != '') {
                $query->where('m.street_id', $this->streetCode);
            } else {
                $query->where('m.area_id', $this->areaCode);
            }
        })->when($date, function ($query, $date) use ($paid) {
            if (!$paid) {
                getModelTime($query, $date, 'o.create_time');
            } else
                getModelTime($query, $date, 'pay_time');
        })->group('o.uid')->count();
    }

    public function orderPrice($date, $paid = null)
    {
        return StoreOrder::getDB()->alias('o')->join('merchant m', 'o.mer_id=m.mer_id')->when($paid, function ($query, $paid) {
            $query->where('o.paid', $paid);
        })->where( function ($query) {
            if ($this->streetCode != '') {
                $query->where('m.street_id', $this->streetCode);
            } else {
                $query->where('m.area_id', $this->areaCode);
            }
        })->when($date, function ($query, $date) use ($paid) {
            if (!$paid) {
                $query->where(function ($query) use ($date) {
                    $query->where(function ($query) use ($date) {
                        $query->where('o.paid', 1);
                        getModelTime($query, $date, 'pay_time');
                    })->whereOr(function ($query) use ($date) {
                        $query->where('o.paid', 0);
                        getModelTime($query, $date, 'o.create_time');
                    });
                });
            } else
                getModelTime($query, $date, 'pay_time');
        })->sum('o.pay_price');
    }
}