<?php

namespace App\Http\Middleware;

use Closure;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Classes\Modules\Transactions\Services\ListsGroups;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\CompanyConnection;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class CheckForStorageInvoiceByTransactions
{

    /** @var CheckStorageInvoiceTransactionProcessor */
    private $storageInvoiceTransactionProcessor;

    /** @var ListsTransactions */
    private $listsTransactions;

    /** @var ListsGroups */
    private $listsGroups;


    public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor, ListsTransactions $listsTransactions, ListsGroups $listsGroups)
    {
        $this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
        $this->listsTransactions = $listsTransactions;
        $this->listsGroups = $listsGroups;
    }


    /**
     * Handle an incoming request.
     *
     * @param  Request $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        $results = [];
        $transactions = null;
        $marking = $request->route('marking');
        if($marking){ //for web route /customer/{marking}/payment-and-billing
            $connection = CompanyConnection::where('invitee_reference', $marking)->first();
            $company_module_id = $connection->invitee->id;
            $filters = [
                'per_page' => 999,
                'status_in' => [2],
                'receiver' =>  $company_module_id,
                'type_in' => [TransactionType::SHIPPING_INVOICE]
            ];
            $transactions = $this->listsTransactions->execute($filters);
        }
        else{ //for api route /transactions/list
            $filters = json_decode($request->input('filters'), true);
            $filters['type_in'] = [TransactionType::SHIPPING_INVOICE];
            if(json_encode($filters['order_by']) == '{"column":"id","DESC":true}'){
                $filters['order_by_id_desc'] = true;
            }
            unset($filters['order_by']);
            $transactions = $this->listsTransactions->execute($filters);
        }


        if(isset($filters['check_for_storage_invoice'])){
            foreach($transactions as $transaction){
                $packingList = $transaction->owner()->first();
                if($packingList){
                    $order = $packingList->owner()->first();
                    if($order instanceof Order){
                        $storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
                        if($storages){
                            $results = array_merge($results, $storages);
                        }
                    }
                }
            }
        }

        $filteredResults = array_values(array_filter($results, function($item, $key) {
            static $seen = array();
            $hash = md5($item['parentInvoiceId'] . $item['storageInvoiceId']);
            return !isset($seen[$hash]) && ($seen[$hash] = true);
        }, ARRAY_FILTER_USE_BOTH));


        $request->merge(['storages' => $filteredResults]);

        return $next($request);
    }
}
