<?php


namespace App\Filters;


use App\Commodity;
use App\Order;
use App\OrderIssue;
use App\OrderIssueProcessLog;
use App\OrderIssueRejectedBill;
use App\OrderPackage;
use App\OrderPackageCommodities;
use App\RejectedBill;
use App\RejectedBillItem;
use App\Shop;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;


class OrderIssueFilters
{
    protected $request;
    protected $queryBuilder;
    protected $orderQuery;
    protected $commodityQuery;
    protected $orderPackageQuery;
    protected $orderPackageCommodityQuery;
    protected $orderIssueRejectedBIllQuery;
    protected $rejectedBillQuery;
    protected $rejectedBillItemQuery;
    protected $orderIssueProcessLogQuery;
    protected $shopQuery;
    protected $filters = [
        'log_content',
        'is_imported',
        'is_new_rejecting',
        'logistic_id',
        'custom_code',
        'hiddenTag',
        'client_code',
        'consignee_name',
        'consignee_phone',
        'logistic_number',
        'good_barcode',
        'good_name',
        'send_client_code',
        'id_quality_label',
        'id',
        'created_at_start',
        'created_at_end',
        'order_issue_type_id',
        'logistic_indemnity_money',
        'baoshi_indemnity_money',
        'rejectingStatus',
        'order_issue_ids',
        'settlement_at_start',
        'settlement_at_end',
        'sendOrderClientCode',
        'sendOrderLogisticNumber',
        'user_workgroups',
        'shop_name',
        'finance_confirm',
        'logistic_number_return',
        'final_status',
        'user_owner_group_id',
        'archive_at_start',
        'archive_at_end',
    ];
    protected $array_filter;
    protected $params = [];

    public function __construct(Request $request)
    {
        $this->request = $request;
        $this->params = $request->all();
        $this->array_filter = array_filter($this->request->only($this->filters));
    }

    private function getOrderQuery()
    {
        if(!$this->orderQuery)
            $this->orderQuery = Order::query()->selectRaw('id');
        return $this->orderQuery;
    }

    private function getCommodityQuery()
    {
        if(!$this->commodityQuery)
            $this->commodityQuery = Commodity::query()->selectRaw('id');
        return  $this->commodityQuery;
    }

    private function getOrderPackageQuery()
    {
        if(is_null($this->orderPackageQuery))
            $this->orderPackageQuery = OrderPackage::query()->selectRaw('order_packages.order_id');
        return $this->orderPackageQuery;
    }

    private function getRejectedBillQuery()
    {
        if(!$this->rejectedBillQuery)
            $this->rejectedBillQuery= RejectedBill::query()->selectRaw('logistic_number_return');
        return $this->rejectedBillQuery;
    }

    private function getRejectedBillItemQuery()
    {
        if(!$this->rejectedBillItemQuery)
            $this->rejectedBillItemQuery =  RejectedBillItem::query()->selectRaw('id_rejected_bill');
        return $this->rejectedBillItemQuery;
    }

    private function getOrderPackageCommodityQuery()
    {
        if(!$this->orderPackageCommodityQuery)
            $this->orderPackageCommodityQuery = OrderPackageCommodities::query()->selectRaw('order_package_commodities.order_package_id');
        return $this->orderPackageCommodityQuery;
    }

    private function getOrderIssueRejectedBillQuery()
    {
        if(!$this->orderIssueRejectedBIllQuery)
            $this->orderIssueRejectedBIllQuery = OrderIssueRejectedBill::query()->selectRaw('order_issue_id');
        return $this->orderIssueRejectedBIllQuery;
    }

    private function getOrderIssueProcessLogQuery()
    {
        if(!$this->orderIssueProcessLogQuery)
            $this->orderIssueProcessLogQuery = OrderIssueProcessLog::query()->selectRaw('order_issue_id');
        return $this->orderIssueProcessLogQuery;
    }

    private function getShopQuery()
    {
        if(!$this->shopQuery)
            $this->shopQuery = Shop::query()->selectRaw('id');
        return $this->shopQuery;
    }

    public function apply($builder)
    {
        $this->queryBuilder = $builder;
        $this->beforeApply();
        foreach ($this->array_filter as $filter => $value) {
            if (method_exists($this, $filter)) {
                $this->$filter($value, $this->queryBuilder);
            }
        }
        $this->afterApply();
        return $this->queryBuilder;
    }

    private function beforeApply()
    {
        if(empty($this->params['hidden_tag']))
            $this->queryBuilder->whereNull('order_issues.hidden_tag');

        if(isset($this->params['data'])){
            $ids = explode(',',$this->params['data']);
            $this->id($ids);
        }elseif(!($this->params['is_handle'] ?? false) && !($this->params['final_status'] ?? false)){
            if(!(isset($this->params['settlement_at_start']) || isset($this->params['settlement_at_end']) || isset($this->params['archive_at_end']) || isset($this->params['archive_at_start']))) {
                $this->queryBuilder->where(function ($query) {
                    $query->whereNotIn('order_issues.final_status', ['已解决', '已归档'])->orWhereNull('order_issues.final_status');
                });
            }
        }

        $user = Auth::user();
        $owner_ids = $user ? app('UserService')->getPermittingOwnerIds($user) : [];
        if (isset($this->params['owner_id'])){
            $this->searchWay($this->getOrderQuery(),$this->params['owner_id'],'orders.owner_id');
        } else{
            $this->getOrderQuery()->whereIn('owner_id',$owner_ids);
        }

    }

    public function afterApply()
    {
        if($this->commodityQuery)
            $this->getOrderPackageCommodityQuery()->whereIn('commodity_id',$this->commodityQuery);

        if($this->orderPackageCommodityQuery)
            $this->getOrderPackageQuery()->whereIn('order_packages.id',$this->orderPackageCommodityQuery);

        if($this->orderPackageQuery)
            $this->getOrderQuery()->whereIn('order_id',$this->orderPackageQuery);

        if($this->shopQuery)
            $this->getOrderQuery()->whereIn('shop_id',$this->shopQuery);

        if($this->orderQuery)
            $this->queryBuilder->whereIn('order_issues.order_id',$this->orderQuery);

        if($this->rejectedBillItemQuery)
            $this->getRejectedBillQuery()->whereIn('id',$this->rejectedBillItemQuery);

        if($this->rejectedBillQuery)
            $this->getOrderIssueRejectedBIllQuery()->whereIn('logistic_number_return',$this->rejectedBillQuery);

        if($this->orderIssueRejectedBIllQuery)
            $this->queryBuilder->whereIn('order_issues.id',$this->orderIssueRejectedBIllQuery);

        if($this->orderIssueProcessLogQuery)
            $this->queryBuilder->whereIn('order_issues.id',$this->orderIssueProcessLogQuery);
    }

    private function isSearchLike($str)
    {
        if (substr($str, 0, 1) == "%" || substr($str, strlen($str) - 1, 1) == "%") {
            return true;
        }
        return false;
    }

    private function searchWay($query, $param, $column)
    {
        if ($this->isSearchLike($param)) {
            $query->where($column, 'like', $param);
        } else {
            $query->whereIn($column, array_filter(preg_split('/[,， ]+/is', $param)));
        }
        return $query;
    }

    public function log_content($log_content)
    {
        $order_issue_process_log_query = OrderIssueProcessLog::query()->selectRaw('order_issue_id')->where('content','like',$log_content);
        if(!$this->params['addtime']){
            $order_issue_process_log_query->where('created_at', '>=', Carbon::now()->subDays(31));
        }else{
            $order_issue_process_log_query->where('created_at', '>=', Carbon::now()->subDays($this->params['addtime']));
        }
        $this->queryBuilder->whereIn('order_issues.id',$order_issue_process_log_query);
    }

    public function is_imported($is_imported)
    {
        $this->queryBuilder->where('order_issues.imported_status',$is_imported);
    }

    public function is_new_rejecting($is_new_rejecting)
    {
        $this->queryBuilder->where('order_issues.is_new_rejecting',$is_new_rejecting);
    }

    public function logistic_id($logistic_id)
    {
        $this->getOrderQuery()->where('orders.logistic_id',$logistic_id);
    }

    public function custom_code($custom_code)
    {
        $this->queryBuilder->where('order_issues.custom_code',$custom_code);
    }

    public function hiddenTag($hiddenTag)
    {
        $this->queryBuilder->where('order_issues.hidden_tag',$hiddenTag);
    }

    public function client_code($client_code)
    {
        $this->searchWay($this->getOrderQuery(),$client_code,'orders.client_code');
    }

    public function consignee_name($consignee_name)
    {
        $this->searchWay($this->getOrderQuery(),$consignee_name,'orders.consignee_name');
    }

    public function consignee_phone($consignee_name)
    {
        $this->searchWay($this->getOrderQuery(),$consignee_name,'orders.consignee_phone');
    }

    public function logistic_number($logistic_number)
    {
        $this->searchWay($this->getOrderPackageQuery(),$logistic_number,'logistic_number');
    }

    public function good_barcode($good_barcode)
    {
        $this->searchWay($this->getCommodityQuery(),$good_barcode,'sku');
    }

    public function good_name($good_name)
    {
        $this->searchWay($this->getCommodityQuery(),$good_name,'name');
    }

    public function send_client_code($send_client_code)
    {
        $this->searchWay($this->queryBuilder,$send_client_code,'order_issues.second_client_no');
    }

    public function logistic_number_return($logistic_number_return)
    {
        $this->searchWay($this->getOrderIssueRejectedBillQuery(),$logistic_number_return,'logistic_number_return');
     }

    public function id_quality_label($id_quality_label)
    {
        $this->getRejectedBillItemQuery()->where('id_quality_label',$id_quality_label);
    }

    public function id($id)
    {
        $this->queryBuilder->whereIn('order_issues.id',$id);
    }

    public function created_at_start($created_at_start)
    {
        $this->queryBuilder->where('order_issues.created_at', '>=', $created_at_start . " 00:00:00");
    }

    public function created_at_end($created_at_end)
    {
        $this->queryBuilder->where('order_issues.created_at', '<=', $created_at_end . " 23:59:59");
    }

    public function order_issue_type_id($order_issue_type_id)
    {
        $this->searchWay($this->queryBuilder,$order_issue_type_id,'order_issues.order_issue_type_id');
    }

    public function logistic_indemnity_money($logistic_indemnity_money)
    {
        if($logistic_indemnity_money==='是')
            $this->queryBuilder->whereNotNull('order_issues.logistic_indemnity_money');
        elseif($logistic_indemnity_money==='否')
            $this->queryBuilder->whereNull('order_issues.logistic_indemnity_money');
    }

    public function baoshi_indemnity_money($baoshi_indemnity_money)
    {
        if($baoshi_indemnity_money==='是')
            $this->queryBuilder->whereNotNull('order_issues.baoshi_indemnity_money');
        elseif($baoshi_indemnity_money==='否')
            $this->queryBuilder->whereNull('order_issues..baoshi_indemnity_money');
    }

    public function rejectingStatus($rejectingStatus)
    {
        $this->queryBuilder->where('order_issues.rejecting_status',$rejectingStatus);
    }

    public function order_issue_ids($order_issue_ids)
    {
        $this->searchWay($this->queryBuilder,$order_issue_ids,'order_issues.id');
    }

    public function settlement_at_start($settlement_at_start)
    {
        $this->getOrderIssueProcessLogQuery()->where('created_at','>=',$settlement_at_start.' 00:00:00')->where('type','结束');
    }

    public function settlement_at_end($settlement_at_end)
    {
        $this->getOrderIssueProcessLogQuery()->where('created_at','<=',$settlement_at_end.' 23:59:59')->where('type','结束');
    }

    public function sendOrderClientCode($sendOrderClientCode)
    {
        $this->searchWay($this->queryBuilder,$sendOrderClientCode,'order_issues.second_client_no');
    }

    public function user_workgroups($user_work_groups)
    {
        if(is_string($user_work_groups)){
            $user_work_groups = explode(',', $user_work_groups);
        }
        if(in_array('空',$user_work_groups)){
            $this->queryBuilder->whereNotIn('order_issues.id',function($query)use($user_work_groups){
                $query->from('order_issue_user_workgroup')->selectRaw('order_issue_id');
            });
        }else{
            $this->queryBuilder->whereIn('order_issues.id',function($query)use($user_work_groups){
                $query->from('order_issue_user_workgroup')->selectRaw('order_issue_id')->whereIn('user_workgroup_id',$user_work_groups);
            });
        }
    }

    public function sendOrderLogisticNumber($sendOrderLogisticNumber)
    {
        $order_issue_query = OrderIssue::query()->selectRaw('id');
        $this->searchWay($order_issue_query,$sendOrderLogisticNumber,'second_logistic_number');
        $order_issues = $order_issue_query->get();
        if(count($order_issues)>0){
            $this->queryBuilder->where('order_issues.id',$order_issues->map(function($orderIssue){
                return $orderIssue->id;
            }));
        }
        $orders = Order::query()->selectRaw('client_code')->whereIn('id',function($query)use($sendOrderLogisticNumber){
            $query->from('order_packages')->selectRaw('order_id');
            $this->searchWay($query,$sendOrderLogisticNumber,'logistic_number');
        })->get();
         if($orders->count()>0){
            $this->queryBuilder->where('order_issues.second_client_no',$orders->map(function($order){
                return $order->client_code;
            }));
        }
    }

    public function shop_name($shop_name)
    {
        $this->searchWay($this->getShopQuery(),$shop_name,'name');
        if (isset($this->params['shop_name_limit_time'])) {
            $this->queryBuilder->Where('order_issues.created_at','>=', Carbon::now()->subDays($this->params['shop_name_limit_time']));
        } else {
            $this->queryBuilder->Where('order_issues.created_at','>=', Carbon::now()->subDays(31));
        }
    }

    public function final_status($final_status)
    {
        if($final_status === 'null')
            $this->queryBuilder->whereNull('order_issues.final_status');
        else
            $this->queryBuilder->where('order_issues.final_status',$final_status);

    }

    public function finance_confirm($finance_confirm)
    {
        $this->queryBuilder->where('order_issues.finance_confirm',$finance_confirm);
    }

    public function user_owner_group_id($user_owner_group_id)
    {
        $this->queryBuilder->where('order_issues.user_owner_group_id',$user_owner_group_id);
    }

    public function archive_at_start($archive_at_start)
    {
        $this->queryBuilder->where('order_issues.archive_at','>=',$archive_at_start.' 00:00:00');
    }

    public function archive_at_end($archive_at_end)
    {
        $this->queryBuilder->where('order_issues.archive_at','<=',$archive_at_end.' 23:59:59');
    }

}
