<?php

namespace app\admin\controller\shop;

use app\admin\controller\BaseController;
use app\common\model\OrderModel;
use app\common\model\OrderProductModel;
use app\common\model\OrderRefundModel;
use app\common\model\PayOrderModel;
use shirne\excel\Excel;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use think\Db;
use think\Exception;

/**
 * 订单管理
 * Class OrderController
 * @package app\admin\controller\shop
 */
class OrderController extends BaseController
{
    /**
     * 订单列表
     * @param string $keyword
     * @param string $start_date
     * @param string $end_date
     * @param string $status
     * @param string $audit
     * @return mixed|\think\response\Redirect
     */
    public function index($keyword='',$start_date='',$end_date='',$status='',$audit=''){
        if($this->request->isPost()){
            return redirect(url('',['status'=>$status,'start_date'=>$start_date,'end_date'=>$end_date,'audit'=>$audit,'keyword'=>base64url_encode($keyword)]));
        }
        $keyword=empty($keyword)?"":base64url_decode($keyword);
        $model=Db::view('order','*')
            ->view('member',['username','realname','nickname','avatar','level_id'],'member.id=order.member_id','LEFT')
            ->where('order.delete_time',0);

        if(!empty($keyword)){
            $model->whereLike('order.order_no|member.username|member.nickname|member.realname|order.receive_name|order.mobile',"%$keyword%");
        }
        if($status!==''){
            $model->where('order.status',$status);
        }
        if($audit!==''){
            $model->where('order.isaudit',$audit);
        }
        if($start_date !== ''){
            if($end_date !== ''){
                $model->whereBetween('order.create_time',[strtotime($start_date),strtotime($end_date.' 23:59:59')]);
            }else{
                $model->where('order.create_time','GT',strtotime($start_date));
            }
        }else{
            if($end_date !== ''){
                $model->where('order.create_time','LT',strtotime($end_date.' 23:59:59'));
            }
        }

        $lists=$model->where('order.delete_time',0)->order(Db::raw('if(order.status>-1,order.status,3) ASC,order.create_time DESC'))->paginate(15);
        if(!$lists->isEmpty()) {
            $orderids = array_column($lists->items(), 'order_id');
            $prodata = Db::name('OrderProduct')->where('order_id', 'in', $orderids)->select();
            $products=array_index($prodata,'order_id',true);
            $lists->each(function($item) use ($products){
                if(isset($products[$item['order_id']])){
                    $item['products']=$products[$item['order_id']];
                }else {
                    $item['products'] = [];
                }
                return $item;
            });
        }

        $this->assign('keyword',$keyword);
        $this->assign('start_date',$start_date);
        $this->assign('end_date',$end_date);
        $this->assign('status',$status);
        $this->assign('orderids',empty($orderids)?0:implode(',',$orderids));
        $this->assign('audit',$audit);
        $this->assign('expresscodes',config('express.'));
        $this->assign('lists',$lists);
        $this->assign('levels',getMemberLevels());
        $this->assign('page',$lists->render());
        return $this->fetch();
    }

    /**
     * 导出订单
     * @param $order_ids
     * @param string $keyword
     * @param string $start_date
     * @param string $end_date
     * @param string $status
     * @param string $audit
     * @param string $mode
     */
    public function export($order_ids='',$keyword='',$start_date='',$end_date='',$status='',$audit='', $mode=''){
        $keyword=empty($keyword)?"":base64_decode($keyword);
        $model=Db::view('order','*')
            ->view('member',['username','realname','nickname','avatar','level_id'],'member.id=order.member_id','LEFT')
            ->where('order.delete_time',0);
        if(empty($order_ids)){
            if(!empty($keyword)){
                $model->whereLike('order.order_no|member.username|member.realname|order.receive_name|order.mobile',"%$keyword%");
            }
            if($status!==''){
                $model->where('order.status',$status);
            }
            if($audit!==''){
                $model->where('order.isaudit',$audit);
            }

            if($start_date !== ''){
                if($end_date !== ''){
                    $model->whereBetween('order.create_time',[strtotime($start_date),strtotime($end_date.' 23:59:59')]);
                }else{
                    $model->where('order.create_time','GT',strtotime($start_date));
                }
            }else{
                if($end_date !== ''){
                    $model->where('order.create_time','LT',strtotime($end_date.' 23:59:59'));
                }
            }
        }elseif($order_ids=='status') {
            $model->where('status',1);
        }else{
            $model->whereIn('order.order_id',idArr($order_ids));
        }


        $rows=$model->order('order.create_time DESC')->select();
        if(empty($rows)){
            $this->error('没有选择要导出的项目');
        }

        if($mode == 'express'){
            $this->exportForExpress($rows);
        }else{
            $this->exportData($rows);
        }
    }

    private function exportData($rows){
        $excel=new Excel();
        $excel->setHeader(array(
            '编号','状态','时间','会员ID','会员账号','购买产品','购买价格','收货人','电话','省','市','区','地址'
        ));
        $excel->setColumnType('A',DataType::TYPE_STRING);
        $excel->setColumnType('D',DataType::TYPE_STRING);
        $excel->setColumnType('I',DataType::TYPE_STRING);

        foreach ($rows as $row){
            $prodata = Db::name('OrderProduct')->where('order_id', $row['order_id'])->find();
            $username = $row['username'];
            if(strpos($username,'#') === 0){
                $username = filter_emoji($row['nickname'], '?');
            }
            $excel->addRow(array(
                $row['order_no'],order_status($row['status'],false),date('Y/m/d H:i:s',$row['create_time']),$row['member_id'],$username,
                $prodata['product_title'],$row['payamount'],$row['receive_name'],$row['mobile'],$row['province'],$row['city'],$row['area'],$row['address']
            ));
        }

        $excel->output(date('Y-m-d-H-i').'-订单导出['.count($rows).'条]');
    }

    private function exportForExpress($rows){
        $excel=new Excel();
        $excel->setHeader(array(
            '','收件信息','','','物品信息','','备注'
        ));
        $excel->getSheet()->setMergeCells(['B1:D1','E1:F1']);
        $excel->setHeader(array(
            '编号','收件人姓名','收件人联系方式','收件地址','物品类','物品详情','备注信息'
        ));
        $excel->setColumnType('A',DataType::TYPE_STRING);
        $excel->setColumnType('C',DataType::TYPE_STRING);

        foreach ($rows as $row){
            $prodata = Db::name('OrderProduct')->where('order_id', $row['order_id'])->select();
            $prods = [];
            foreach($prodata as $prod){
                if(count($prods) > 2){
                    $prods[2] .= '等';
                    break;
                }
                $prods[]=$prod['product_title'];
            }
            $excel->addRow(array(
                $row['order_no'],$row['receive_name'],$row['mobile'],$row['province'].$row['city'].$row['area'].$row['address'],
                '食品',implode('、',$prods),''
            ));
        }

        $excel->output(date('Y-m-d-H-i').'-订单发货['.count($rows).'条]');
    }

    /**
     * 订单详情
     * @param $id
     * @return \think\Response
     */
    public function detail($id){
        $model=Db::name('Order')->where('order_id',$id)->find();
        if(empty($model))$this->error('订单不存在');
        $member=Db::name('Member')->find($model['member_id']);
        $products = OrderProductModel::where('order_id',  $id)->select();
        $payorders = PayOrderModel::filterTypeAndId('order',$id)->select();
        $refunds = [];
        if($model['status'] < -1){
            $refunds = OrderRefundModel::where('order_id', $id)->select();
        }
        $this->assign('model',$model);
        $this->assign('member',$member);
        $this->assign('products',$products);
        $this->assign('payorders',$payorders);
        $this->assign('expresscodes',config('express.'));
        $this->assign('refunds',$refunds);
        return $this->fetch();
    }

    public function setstatus($ids){
        $ids = idArr($ids);
        $status = $this->request->param('status');

        $orders = OrderModel::whereIn('order_id',$ids)->select();
        if(empty($orders)){
            $this->error('参数无效');
        }
        $errors=[];
        foreach($orders as $order){
            if($order['status'] < 1){
                $errors[] = '订单['.$order['order_id'].']状态错误';
                continue;
            }
            if($order['status'] < $status){
                for($i=$order['status']+1;$i<=$status;$i++){
                    $order->updateStatus($i);
                }
            }
        }

        $this->success(implode("\n",$errors)."\n操作完成");
    }

    public function setcancel($id){
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        if($order['status'] > 0){
            $this->error('订单不可取消');
        }
        $order->updateStatus(['status'=>-1]);
        user_log($this->mid,'cancelorder',1,'取消订单 '.$id ,'manager');
        $this->success('操作成功');
    }
    public function setpayed($id){
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        if($order['status'] < 0){
            $this->error('订单已失效');
        }
        if($order['status'] >= 1){
            $this->error('订单已支付');
        }
        $paytype=$this->request->post('paytype');
        if($paytype == 'balance'){
            $debit = money_log($order['member_id'], -$order['payamount']*100, "订单支付", 'consume',0,'money');
            if(!$debit){
                $this->error('用户余额不足');
            }
        }else{
            $paytype = 'offline';
        }
        $order->updateStatus(['status'=>1,'pay_type'=>$paytype]);
        user_log($this->mid,'orderpay',1,'订单支付 '.$id ,'manager');
        $this->success('操作成功');
    }
    public function setdelivery($id){
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        if($order['status'] < 0){
            $this->error('订单已失效');
        }
        if($order['status'] < 1){
            $this->error('订单未支付');
        }
        if($order['status'] > 2){
            $this->error('订单已发货');
        }
        $express_no=$this->request->post('express_no');
        $express_code=$this->request->post('express_code');
        
        $order->updateStatus([
            'status'=>2,
            'express_no'=>$express_no,
            'express_code'=>$express_code
        ]);
        user_log($this->mid,'orderdelivery',1,'订单发货 '.$id ,'manager');
        $this->success('操作成功');
    }
    public function setreceive($id){
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        if($order['status'] < 0){
            $this->error('订单已失效');
        }
        if($order['status'] < 2){
            $this->error('订单未发货');
        }
        if($order['status'] >= 3){
            $this->error('订单已完成');
        }
        $order->updateStatus(['status'=>3]);
        user_log($this->mid,'orderconfirm',1,'订单确认 '.$id ,'manager');
        $this->success('操作成功');
    }

    public function setcomplete($id){
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        if($order['status'] < 0){
            $this->error('订单已失效');
        }
        if($order['status'] < 3){
            $this->error('订单未收货');
        }
        if($order['status'] >= 4){
            $this->error('订单已完成');
        }
        $order->updateStatus(['status'=>4]);
        user_log($this->mid,'ordercomplete',1,'订单完成 '.$id ,'manager');
        $this->success('操作成功');
    }

    /**
     * 订单进度修改
     * @param $id
     */
    public function status($id){
        $this->error('操作已失效');
    }
    
    
    
    /**
     * 改价
     * @param $id
     * @param $price
     * @throws Exception
     */
    public function reprice($id,$price)
    {
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        if($order['status']!=0){
            $this->error('订单当前状态不可改价');
        }
        $price=$this->request->post('price');
        
        $data=array(
            'payamount'=>round(floatval($price),2)
        );
        
        $order->save($data);
        user_log($this->mid,'repriceorder',1,'订单改价 '.$id .' '.$price,'manager');
        $this->success('操作成功');
    }

    /**
     * 支付订单查询
     * @param $id
     */
    public function paystatus($id){
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        if($order['status']!=0){
            $this->error('订单当前状态非待支付');
        }
        $payorders = PayOrderModel::filterTypeAndId('order',$id)->select();
        if(empty($payorders)){
            $this->error('该订单没有在线支付记录');
        }
        foreach($payorders as $porder){
            $porder->checkStatus();
        }
        
        $this->success('操作成功', null, ['lists'=>$payorders]);
    }

    /**
     * 支付状态查询 todo
     * @param $payid
     */
    public function payquery($payid){
        $payorder = PayOrderModel::get($payid);
        if(empty($payorder)){
            $this->error('支付订单不存在');
        }
        $result=$payorder->checkStatus();
        if($result){
            if($payorder->getErrNo()){
                $this->error('查询成功：'.$payorder->getError());
            }else{
                $this->success('订单已支付');
            }
        }else{
            $this->error($payorder->getError());
        }
    }

    /**
     * 审核订单
     * @param $id
     */
    public function audit($id){
        $order = OrderModel::get($id);
        if(empty($id) || empty($order)){
            $this->error('订单不存在');
        }
        $audit=$this->request->post('status/d');
        
        $order->audit();
        user_log($this->mid,'auditorder',1,'审核订单 '.$id .' '.$audit,'manager');
        $this->success('操作成功');
    }

    /**
     * 删除订单
     * @param $id
     */
    public function delete($id)
    {
        $model = Db::name('order');
        $result = $model->whereIn("order_id",idArr($id))->useSoftDelete('delete_time',time())->delete();
        if($result){
            //Db::name('orderProduct')->whereIn("order_id",idArr($id))->delete();
            user_log($this->mid,'deleteorder',1,'删除订单 '.$id ,'manager');
            $this->success(lang('Delete success!'), url('shop.order/index'));
        }else{
            $this->error(lang('Delete failed!'));
        }
    }

    public function refundcancel($id, $reason = ''){
        $refund = OrderRefundModel::where('id',$id)->find();
        if(empty($refund) || $refund['status'] != 0){
            $this->error('该投诉已处理过了');
        }
        $refund->save([
            'status'=>-1,
            'reply'=>$reason
        ]);
        $order = OrderModel::where('order_id',$refund['order_id'])->find();
        
        user_log($this->mid,'orderrefundcancel',1,'拒绝退款单 '.$id ,'manager');
        $this->success('处理成功');
    }

    public function refundallow($id){
        $refund = OrderRefundModel::where('id',$id)->find();
        if(empty($refund) || $refund['status'] != 0){
            $this->error('该投诉已处理过了');
        }
        $order = OrderModel::where('order_id',$refund['order_id'])->find();
        if(empty($order) || $order['status'] < 1){
            $this->error('订单状态错误');
        }
        
        if($order['pay_type'] == 'balance'){
            $loged = money_log($order['member_id'], $order['payamount'], "订单退款", 'refund',0,'money');
            if($loged){
                $refund->save([
                    'status'=>1,
                    'reply'=>'success'
                ]);
            }else{
                $this->success('退款失败');
            }
        }else{
            $refunded = PayOrderModel::refund($refund['order_id'], 'order', $refund['type']);
            if($refunded){
                $refund->save([
                    'status'=>1,
                    'reply'=>'process'
                ]);
            }else{
                $this->success('退款申请失败');
            }
        }
        user_log($this->mid,'orderrefundallow',1,'通过退款单 '.$id ,'manager');
        $this->success('处理成功');
    }
}