<?php

namespace app\admin\controller;

use app\model\Admins;
use app\model\Backs;
use app\model\Finances;
use app\model\Onlines;
use app\model\Orders;
use DateTime;
use Qiniu\Auth;
use support\Log;
use support\Redis;
use support\Request;

class IndexController extends base
{

    public function isWork(Request $request)
    {
        Redis::set('CRM:USER:ONLINE:WATCH:' . $request->admin->id, time());

        $lastTime = Redis::get('CRM:USER:ONLINE:' . $request->admin->id);
        $end = Redis::hGet('CRM:USER:ONLINE:END', $request->admin->id);
        if (!empty($lastTime) && time() - $lastTime <= 5 * 60) {
        } elseif (empty($lastTime) && $end) {
            $has = Onlines::where("admin_id", $request->admin->id)->order('id desc')->find();
            if ($has && empty($has->end)) {
                Onlines::where("id", $has->id)->update(['end' => $end]);
            } else {
                $start = Redis::hGet('CRM:USER:ONLINE', $request->admin->id);
                //创建一个新的
                Onlines::create([
                    'admin_id' => $request->admin->id,
                    'start' => $start,
                    'end' => $end
                ]);
            }
            //创建一个新的
            Onlines::create([
                'admin_id' => $request->admin->id,
                'start' => time(),
                'end' => 0
            ]);
        } else {
            //第一次,给建个新的
            Onlines::create([
                'admin_id' => $request->admin->id,
                'start' => time(),
                'end' => 0
            ]);
        }

        Redis::Set('CRM:USER:ONLINE:' . $request->admin->id, time(), 'ex', 10 * 60);
        Redis::hSet('CRM:USER:ONLINE:END', $request->admin->id, time() + 60);


        $new = Redis::get('CRM:USER:ONLINE:NEW:' . $request->admin->id);
        Redis::del('CRM:USER:ONLINE:NEW:' . $request->admin->id);
        $back = Redis::set('CRM:USER:ONLINE:FOLLOW:LOCK:' . $request->admin->id, time(), 'EX', 60, 'nx');
        $follow = $backs = 0;
        if ($back) {
            $follow = Orders::where('admin_id', $request->admin->id)->whereBetween('next_follow', [1, (time() - 60) * 1000])->count();
            $backs = Backs::where('admin', $request->admin->id)->where('status', 0)->count();
        }

        // 核销提醒
        $orderWriteOff = Redis::get('CRM:USER:WRITE:OFF:' . $request->admin->id);
        Redis::del('CRM:USER:WRITE:OFF:' . $request->admin->id);

        // 跟进提醒
        $followMessage = 0;
        $followOrderId = '';
        $appointmentNum = 0;
        if ($request->admin->id > 1) {
            $start = strtotime(date('Y-m-d')) * 1000;
            $end = strtotime(date('Y-m-d', strtotime('+1 days'))) * 1000 - 1;
            $followMessageList = Orders::where(['admin_id' => $request->admin->id])
                ->whereBetween('next_follow', [$start, $end])
                ->where('status', 1)
                ->field(['id'])
                ->select();
            $followMessage = count($followMessageList);
            if ($followMessage) {
                $followOrderId = $followMessageList[0]['id'];
            }

            // 预约未处理数量
            $appointmentNum = Orders::where(['admin_id' => $request->admin->id])
                ->where('appointment_status', 1)
                ->count();
        }

        return $this->success(['new' => $new ?? 0, 'follow' => $follow, 'back' => $backs, 'order_write_off' => $orderWriteOff, 'follow_message' => $followMessage, 'follow_order_id' => $followOrderId, 'appointment_num' => $appointmentNum]);
    }

    public function line()
    {
        $time = strtotime(date('Y-m-d'));
        $data = [];
        for ($i = 10; $i > 0; $i--) {
            $_time = $time - 3600 * 24 * $i;
            $d = Finances::whereBetween('create_time', [$_time, $_time + 24 * 3600 - 1])
                ->where('status', 1)
                ->fieldRaw('SUM(IF(type=1,`total`,0))/100 as total, SUM(IF(type=2,`total`,0))/100 as refund')
                ->find();
            $d->date = date("m-d", $_time);
            $data[] = $d;
        }
        $_data = [];
        foreach ($data as $d) {
            $_data['title'][] = trim($d->date);
            $_data['total'][] = $d->total ?? 0;
            $_data['refund'][] = abs($d->refund ?? 0);
        }
        return $this->success($_data);
    }

    public function orders(Request $request)
    {
        // 获取当天结束时间（23:59:59）
        $currentTime = new DateTime();
        $currentTime->setTime(23, 59, 59);
        $endOfDayTimestamp = $currentTime->getTimestamp() * 1000;

        // 获取前30天的开始时间（00:00:00）
        $thirtyDaysAgo = new DateTime('-30 days');
        $thirtyDaysAgo->setTime(0, 0, 0);
        $startOfThirtyDaysAgoTimestamp = $thirtyDaysAgo->getTimestamp() * 1000;

        // 获取前60天的开始时间（00:00:00）
        $sixtyDaysAgo = new DateTime('-60 days');
        $sixtyDaysAgo->setTime(0, 0, 0);
        $startOfSixtyDaysAgoTimestamp = $sixtyDaysAgo->getTimestamp() * 1000;

        // 获取前80天的开始时间（00:00:00）
        $eightyDaysAgo = new DateTime('-80 days');
        $eightyDaysAgo->setTime(0, 0, 0);
        $startOfEightyDaysAgoTimestamp = $eightyDaysAgo->getTimestamp() * 1000;

        /*SUM(IF(asset_price>0 AND status=2,1,0)) as asset,
          SUM(IF(asset_price>0 AND status=2,asset_price,0)) as asset_price,*/
        $order = Orders::where('sn', '>', 0)
            ->fieldRaw('
            SUM(IF(status=0,1,0)) as wait, 
            SUM(IF(status=1,1,0)) as doing, 
            SUM(total_price) as total,
            COUNT(id) as `all`,
            SUM(CASE   
                 WHEN (os in(1,7) AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os in (3,5) AND order_status = 1) THEN 1  
                 ELSE 0  
               END) as tobeused, 
            SUM(CASE   
                 WHEN (os in(1,7) AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os in (3,5) AND order_status = 1) THEN total_price  
                 ELSE 0  
               END) as tobeused_price,
            SUM(CASE   
                 WHEN (os in(1,7) AND order_status = 4) OR (os in (3,5) AND order_status = 2) OR (os = 2 AND order_status = 5) THEN 1  
                 ELSE 0  
               END) as asset, 
            SUM(CASE   
                 WHEN (os in(1,7) AND order_status = 4) OR (os in (3,5) AND order_status = 2) OR (os = 2 AND order_status = 5) THEN asset_price  
                 ELSE 0  
               END) as asset_price,
            SUM(CASE   
                 WHEN ((os in(1,7) AND status = 5) OR (os in (3,5) AND status = 4) OR (os = 2 AND status = 1)) THEN 1  
                 ELSE 0  
               END) AS refund,  
            SUM(CASE   
                 WHEN ((os in(1,7) AND status = 5) OR (os in (3,5) AND status = 4) OR (os = 2 AND status = 1)) THEN actual_price  
                 ELSE 0  
               END) AS refund_price,
            SUM(CASE   
                 WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfThirtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN 1  
                 ELSE 0  
               END) AS tobeused_30,  
            SUM(CASE   
                 WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfThirtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN total_price  
                 ELSE 0  
               END) AS tobeused_price_30,
            SUM(CASE   
                 WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfSixtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN 1  
                 ELSE 0  
               END) AS tobeused_60,  
            SUM(CASE   
                 WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfSixtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN total_price  
                 ELSE 0  
               END) AS tobeused_price_60,
            SUM(CASE   
                 WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfEightyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN 1  
                 ELSE 0  
               END) AS tobeused_80,  
            SUM(CASE   
                 WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfEightyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN total_price  
                 ELSE 0  
               END) AS tobeused_price_80
        ');

        if ($request->admin->id != 1) {
            $order = $order->where('admin_id', $request->admin->id);
        }

        $order = $order->find();

        return $this->success([
            'wait' => $order->wait ?? 0,
            'doing' => $order->doing ?? 0,
            'total' => $order->total ?? 0,
            'all' => $order->all ?? 0,
            'tobeused' => $order->tobeused ?? 0,
            'tobeused_price' => $order->tobeused_price ?? 0,
            'asset' => $order->asset ?? 0,
            'asset_price' => $order->asset_price ?? 0,
            'refund' => $order->refund ?? 0,
            'refund_price' => $order->refund_price ?? 0,
            'tobeused_30' => $order->tobeused_30 ?? 0,
            'tobeused_price_30' => $order->tobeused_price_30 ?? 0.00,
            'tobeused_60' => $order->tobeused_60 ?? 0,
            'tobeused_price_60' => $order->tobeused_price_60 ?? 0.00,
            'tobeused_80' => $order->tobeused_80 ?? 0,
            'tobeused_price_80' => $order->tobeused_price_80 ?? 0.00
        ]);
    }


    public function pie()
    {
        $time = strtotime(date('Y-m-d'));
        $_time = $time - 3600 * 24 * 10;
        $data = Orders::whereBetween('create_time', [$_time, time()])->fieldRaw('sum(total_price) as value, status')->group('status')->select();
        $ddd = [];
        foreach (Orders::StatusName as $k => $d) {
            $item['name'] = $d;
            $item['value'] = 0;
            foreach ($data as $dd) {
                if ($dd->status == $k) {
                    $item['value'] = $dd->value / 100;
                    break;
                }
            }
            $ddd[] = $item;
        }

        return $this->success($ddd);
    }

    public function Info(Request $request)
    {
        $info = Admins::where('id', $request->admin->id)->find();

        $roles = ['editor'];
        if ($info->is_super) {
            $roles = ['admin'];
        }

        if ($info->is_franchisee) {
            $roles = ['franchisee'];
        }

        return $this->success([
            'roles' => $roles,
            'avatar' => $info->avatar ?? '/avatar.webp',
            'name' => $info->name,
            'is_anchor' => $info->is_anchor ? 1 : 0,
            'oss' => Orders::OSS
        ]);

    }

    public function qiniu()
    {
        // 用于签名的公钥和私钥
        $accessKey = config('qiniu.accessKey');
        $secretKey = config('qiniu.secretKey');

        // 初始化签权对象
        $auth = new Auth($accessKey, $secretKey);

        $bucket = 'tt-api';
        $key = 'imgs/' . Date('Ym/d-His') . '.jpg';
        // 生成上传Token
        $token = $auth->uploadToken($bucket);

        return $this->success(['qiniu_key' => $key, 'qiniu_token' => $token, 'qiniu_url' => 'http://up-z2.qiniup.com']);
    }

    public function avatar(Request $request)
    {
        $file = $request->file("file");
        $filename = '/uploads/avatar/' . $request->admin->id . '.' . $file->getUploadExtension();
        $file->move(public_path() . $filename);
        $item = Admins::where('id', $request->admin->id)->find();
        $item->avatar = $filename;
        $item->save();
        return $this->success($filename);
    }

    public function productNameList(Request $request)
    {
        $limit = $request->get('limit', 10);
        $product_name = $request->get('product_name');
        $os = $request->get('os_status');
        $times = $request->get('times');
        $list = Orders::where('id','>',0)
            ->fieldRaw('
            os,product_name,
            SUM(IF(status=0,1,0)) as wait, 
            SUM(IF(status=1,1,0)) as doing,
            SUM(total_price) as total,
            count(id) as `all`,
            SUM(CASE   
                 WHEN (os = 1 AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os = 3 AND order_status = 1) THEN 1  
                 ELSE 0  
               END) as tobeused, 
            SUM(CASE   
                 WHEN (os = 1 AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os = 3 AND order_status = 1) THEN total_price  
                 ELSE 0  
               END) as tobeused_price,
            SUM(CASE   
                 WHEN (os = 1 AND order_status = 4) OR (os = 3 AND order_status = 2) OR (os = 2 AND order_status = 5) THEN 1  
                 ELSE 0  
               END) as asset, 
            SUM(CASE   
                 WHEN (os = 1 AND order_status = 4) OR (os = 3 AND order_status = 2) OR (os = 2 AND order_status = 5) THEN asset_price  
                 ELSE 0  
               END) as asset_price,
            SUM(CASE   
                 WHEN (os = 1 AND order_status = 5) OR (os = 3 AND order_status = 4) OR (os = 2 AND order_status = 1) THEN 1  
                 ELSE 0  
               END) AS refund,  
            SUM(CASE   
                 WHEN (os = 1 AND order_status = 5) OR (os = 3 AND order_status = 4) OR (os = 2 AND order_status = 1) THEN actual_price  
                 ELSE 0  
               END) AS refund_price
            ')
            ->group('os,product_name')
            ->order('all desc');

        if ($request->admin->id !=1){
            $list = $list->where('admin_id', $request->admin->id);
        }

        if($times) {
            if (is_string($times)) {
                $times = explode(',', $times);
            }
            $list = $list->whereBetween('create_at',[strtotime($times[0])*1000,strtotime($times[1])*1000+999]);
        }

        if (!empty($os)){
            $list = $list->where('os',$os);
        }
        if (!empty($product_name)){
            $list = $list->where('product_name','like','%'.$product_name.'%');
        }

        $excel = $request->get('excel');
        if($excel == 1) {
            $orderProducts = $list->select();

            $writer = new \XLSXWriter();
            $writer->writeSheetHeader('产品列表', [
                '产品名称' => 'string',
                '平台' => 'string',
                '订单数' => 'integer',
                '订单金额' => 'price',
                '待更进' => 'integer',
                '跟进中' => 'integer',
                '待使用' => 'integer',
                '待使用金额' => 'price',
                '核销数' => 'integer',
                '核销金额' => 'price',
                '退款数' => 'integer',
                '退款金额' => 'price',
                '核销率' => 'string',
                '退款率' => 'string',
            ]);

            $osList = [
                1 => '美团',
                2 => '快手',
                3 => '抖音',
            ];
            bcscale(2);
            foreach($orderProducts as $product) {
                $writer->writeSheetRow('产品列表', [
                    $product->product_name,
                    $osList[$product->os] ?? '',
                    $product->all,
                    bcdiv($product->total, 100),
                    $product->wait,
                    $product->doing,
                    $product->tobeused,
                    bcdiv($product->tobeused_price, 100),
                    $product->asset,
                    bcdiv($product->asset_price, 100),
                    $product->refund,
                    bcdiv($product->refund_price, 100),
                    number_format(($product['asset']/$product['all'])*100,2) . '%',
                    number_format(($product['refund']/$product['all'])*100,2) . '%',
                ]);
            }

            $file_name = "产品统计-".date('Ymd-His').".xlsx";

            $response = response();
            $c = $writer->writeToString();
            $response->withHeaders([
                'Content-Type' => 'application/force-download',
                'Content-Disposition' => 'attachment; filename="'.$file_name.'"',
                'Content-Transfer-Encoding' => 'binary',
                'Cache-Control' => 'max-age=0',
            ])->withBody($c);
            return $response;
        }

        $list = $list->paginate($limit)->toArray();

        foreach ($list['data'] as &$item) {
//            $item['refund_rate'] = bcmul(bcdiv((string)$item['refund'], (string)$item['all'], 4), '100', 2);
//            $item['asset_rate'] = bcmul(bcdiv((string)$item['asset'], (string)$item['all'], 4), '100', 2);
            $item['refund_rate'] = number_format(($item['refund']/$item['all'])*100,2);
            $item['asset_rate'] = number_format(($item['asset']/$item['all'])*100,2);;
        }

        return $this->success($list);
    }
}