<?php

use App\Classes\Jobs\FetchDeliveryListFromVTPortalJob;
use App\Classes\Jobs\FetchLoadedContainersFromVTPortalJob;
use App\Classes\Jobs\FetchOrdersFromYDPortalJob;
use App\Classes\Jobs\FetchWarehouseReceiveListFromVTPortalJob;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use App\Classes\Modules\PackingLists\Processors\FetchContainersFromYdPortalProcessor;
use App\Classes\Modules\PackingLists\Processors\FetchContainersUpdatesFromYdPortalProcessor;
use App\Classes\Modules\PackingLists\Processors\FetchDeliveryUpdatesFromYdPortalProcessor;
use App\Classes\Modules\PackingLists\Processors\FetchLoadedContainersFromVTPortalProcessor;
use App\Classes\Modules\PackingLists\Processors\FetchPackingListsFromYdPortalProcessor;
use App\Classes\Modules\Transactions\Processors\ApproveShippingInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\BusinessType;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\CompanyConnection;
use App\Models\CompanyModule;
use App\Models\Document;
use App\Models\Order;
use App\Models\Package;
use App\Models\PackingList;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use App\Models\Container;
use App\Models\Transaction;
use App\Models\Wallet;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Route;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

require __DIR__ . '/template.php';

Route::domain('hywave.izyim.com')->group(function () {
    Route::group(['as' => 'last_mile_delivery.'], function () {
        Route::get('/', function () {
            return view('pages.accounts.signup');
        })->name('login');

        Route::get('/dashboard', function () {
            return view('pages.delivery.dashboard');
        })->name('dashboard');

        Route::get('/orders/export', 'Delivery\ExportDeliveryOrdersToExcelController@lineClear')->name('order.export');

    });
});

Route::group(['prefix'=> '/last_mile_delivery', 'as' => 'last_mile_delivery.'], function () {
    Route::get('/', function () {
        return view('pages.accounts.signup');
    })->name('login');

    Route::get('/dashboard', function () {
        return view('pages.delivery.dashboard');
    })->name('dashboard');

    Route::get('/orders/export', 'Delivery\ExportDeliveryOrdersToExcelController@lineClear')->name('order.export');

});

Route::group(['prefix'=> '/air_shipment', 'as' => 'air_shipment.'], function () {
    // Route::get('/', function () {
    //     return view('pages.accounts.signup');
    // })->name('login');

    Route::get('/quotation', function () {
        return view('pages.airShipment.quotation');
    })->name('quotation');
});

Route::get('', function () {
    return view('pages.accounts.login');
})->name('login');

Route::get('/signup', function () {
    return view('pages.accounts.sign_up');
})->name('signup');


Route::group(['prefix' => 'swagger'], function () {
    Route::get('/', function () {
        return view('swagger.index');
    });
    Route::get('/json', function () {
        return view('swagger.json');
    });
});

Route::get('/business/claim/{hash}', function ($hash) {
    return view('pages.accounts.claim_business', ['id' => Crypt::decryptString($hash)]);
})->name('company.claim');

Route::get('/account/email/verification/{token}', function ($token) {
    return view('pages.accounts.email_verified', ['token' => $token]);
})->name('account.email.verification');

Route::get('/account/password/reset/{token}', function ($token) {
    return view('pages.accounts.reset_password', ['token' => $token]);
})->name('account.password.reset');

Route::get('/dashboard', function () {
    return view('pages.dashboard');
})->name('dashboard');

Route::get('/customers', function () {
    return view('pages.admin.customers');
})->name('customers');

Route::get('/orders', function () {
    return view('pages.orders.index');
})->name('orders');

Route::get('/support', function () {
    return view('pages.support', [
        'email'                 => null,
        'orderNo'               => null,
        'orderNoNotFound'       => null,
        'marking'               => null,
        'markingReturn'         => null,
        'markingNotFound'       => null,
    ]);
})->name('support');

Route::post('/support', function (Request $request) {

    $orderNoNotFound = false;
    $orderNo         = $request->input('orderNo');

    $marking         = $request->input('marking');
    $markingReturn   = null;
    $markingNotFound = false;

    if ($orderNo) {
        if (Order::where('reference', $orderNo)->count()) {
            return redirect(route('order.show', $orderNo));
        } else {
            $orderNoNotFound = true;
        }
    }

    if ($marking) {
        $orderNo = null;
        $markingReturn = CompanyConnection::where('invitee_reference', 'LIKE', '%'. $marking .'%')->get();
        $dataReturn = [];
        if (count($markingReturn)) {
            $markingReturn = $markingReturn;
            foreach ($markingReturn as $connection) {
                $company_module         = $connection->invitee;
                $company_module_contact = $company_module->contacts()->first();
                $company                = $company_module->company;
                $company_contact        = $company->contacts()->first();

                $dataReturn[] = json_encode(
                    [
                        'connection'            => $connection ? $connection->toArray() : null,
                        'company_module'         => $company_module ? $company_module->toArray() : null,
                        'company_module_contact' => $company_module_contact ? $company_module_contact->toArray() : null,
                        'company'                => $company ? $company->toArray() : null,
                        'company_contact'        => $company_contact ? $company_contact->toArray() : null,
                    ]
                );

            }
        } else {
            $markingNotFound = true;
        }
    }

    return view('pages.support', [
        'email'                 => null,
        'orderNo'               => $orderNo,
        'orderNoNotFound'       => $orderNoNotFound,
        'marking'               => $marking,
        'markingReturn'         => $dataReturn,
        'markingNotFound'       => $markingNotFound,
    ]);
})->name('support');

Route::get('/orders-table', function () {
    return view('pages.orders.table');
})->name('ordersTable');

Route::get('/order/show/{order_number}', function ($orderNumber) {
    // return view('pages.orders.profile', ['id' => $orderNumber]);
    return view('pages.orders.profile_v2', ['id' => $orderNumber]);
})->name('order.show');

Route::get('/order/v2/show/{order_number}', function ($orderNumber) {
    return view('pages.orders.profile_v2', ['id' => $orderNumber]);
})->name('order.v2.show');

Route::get('/address', function () {
    return view('pages.addresses.index');
})->name('address');

Route::get('/warehouse-list', function () {
    return view('pages.warehouse_list');
})->name('warehouse.list');

Route::get('/delivery-list', function () {
    return view('pages.delivery_list');
})->name('delivery.list');

Route::get('/unclaimed-packinglist', function () {
    return view('pages.unclaimed_packinglist');
})->name('unclaimed-packinglist.list');

Route::get('/containers', function () {
    return view('pages.containers');
})->name('containers');

Route::get('/container/show/{reference}', function ($reference) {
    $container = Container::where('reference', $reference)->first();
    return view('pages.templates.warehouseFlow', ['id' => $container->id]);
})->name('container.show');

Route::get('/customer/{marking}', function ($marking) {
    $connection = CompanyConnection::where('invitee_reference', $marking)->first();
    $id = $connection->invitee->company->id;
    return view('pages.customers.profile', ['id' => $id]);
})->name('customer.profile');

Route::get('/customer/{marking}/details', function ($marking) {
    $connection = CompanyConnection::where('invitee_reference', $marking)->first();
    $id = $connection->invitee->company->id;
    return view('pages.customers.profile_details', ['id' => $id]);
})->name('customer.profile.details');

Route::get('/customer/{marking}/payment-and-billing', function ($marking) {
    $connection = CompanyConnection::where('invitee_reference', $marking)->first();
    $company_module_id = $connection->invitee->id;
    return view('pages.customers.paymentsBilling', ['company_module_id' => $company_module_id]);
})->name('customer.payment-and-billing');
// })->middleware('storage.invoice.check.bytransactions')->name('customer.payment-and-billing');

Route::get('/customer-invoices/{company_module_id}/payment-and-billing', function ($company_module_id) {
    // todo-new: check company_module_id
    return view('pages.customers.paymentsBilling', ['company_module_id' => $company_module_id]);
})->name('customer.payment-and-billing-by-company-module-id');

Route::get('/orders/refresh', function(Request $request){
    $packingLists = PackingList::where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->has('containers')->get();
    dd($packingLists);
    $packingLists->each(function (PackingList $packingList) {
        $packingList->containers()->detach();
    });
    FetchWarehouseReceiveListFromVTPortalJob::withChain([
        new FetchLoadedContainersFromVTPortalJob,
        new FetchOrdersFromYDPortalJob
    ])->dispatch();

    return redirect('orders');

})->name('orders.refresh');

Route::get('/containers/refresh', function(){

    dd((App()->make(FetchLoadedContainersFromVTPortalProcessor::class))->execute());
//    FetchLoadedContainersFromVTPortalJob::dispatch();
//    FetchContainersStatusUpdateFromVTPortalJob::dispatch();

    return redirect('orders');

})->name('containers.refresh');

Route::get('/deliveries/refresh', function(){

    FetchDeliveryListFromVTPortalJob::dispatch();

    return redirect('orders');

})->name('deliveries.refresh');

Route::get('/order/{id}/download', 'Orders\DownloadOrderQrPdfController@download')->name('order.qr.download');

Route::get('/report/customclearance/{orderid}', 'Reports\CustomcClearanceReportController@download')->name('report.customclearance');

Route::group(['prefix' => 'template', 'as' => 'template.'], function () {
    Route::get('/payment-and-billing', function () {
        return view('pages.templates.paymentsBilling');
    })->name('payment-and-billing');

    Route::get('/shipping-queue', function () {
        return view('pages.templates.shippingQueue');
    })->name('shipping-queue');
});

Route::get('/yiwu', function () {
    $orders = Order::whereHas('OrderRoles', function($query){
        return $query->where('role_id', OrderRoleTypes::ORIGIN_WAREHOUSE)->where('company_module_id', 2358);
    })->get();

    foreach ($orders as $order){
        echo '<a target="_blank" href="'.route('order.show', $order->reference).'">'. $order->reference.' - '.$order->created_at.'</a><br>';
    }

});

Route::get('/guangzhou', function () {
    $orders = Order::whereHas('OrderRoles', function($query){
        return $query->where('role_id', OrderRoleTypes::ORIGIN_WAREHOUSE)->where('company_module_id', 3);
    })->whereHas('addresses', function($query){
        return $query->where('status', ApprovalStatus::APPROVED)->whereIn('state_id', [5, 13, 14]);
    })->get();

    foreach ($orders as $order){
        echo '<a target="_blank" href="'.route('order.show', $order->reference).'">'. $order->reference.' - '.$order->created_at.'</a><br>';
    }

});

Route::get('/debug', function (){
    $orders = Order::all();

    $issues = [];
    foreach ($orders as $order){
        $received = $order->parcels()->warehouseReceiveList()->sum('quantity');
        $shipping = $order->parcels()->shippingList()->sum('quantity');
        if( $received < $shipping){
            $issues[] = [
                'order' => $order->reference,
                'received' => $received,
                'shipping' => $shipping
            ];
        }
    }

    dd($issues);
});

Route::group(['prefix' => 'yd', 'as' => 'yd.'], function () {
    Route::get('/packingLists', function (Request $request){
        $start = $request->input('start_date') ? Carbon::parse($request->input('start_date')): null;
        $end = $request->input('end_date') ? Carbon::parse($request->input('end_date')): null;
        (App()->make(FetchPackingListsFromYdPortalProcessor::class))->execute($start, $end);
    });

    Route::get('/containers', function (){
        (App()->make(FetchContainersFromYdPortalProcessor::class))->execute();
        (App()->make(FetchContainersUpdatesFromYdPortalProcessor::class))->execute();
    });

    Route::get('/deliveries', function (){
        (App()->make(FetchDeliveryUpdatesFromYdPortalProcessor::class))->execute();
    });

});
Route::get('/yd', function (Request $request){
    $start = $request->input('start_date') ? Carbon::parse($request->input('start_date')): null;
    $end = $request->input('end_date') ? Carbon::parse($request->input('end_date')): null;
    (App()->make(FetchPackingListsFromYdPortalProcessor::class))->execute($start, $end);
    (App()->make(FetchContainersFromYdPortalProcessor::class))->execute();
    (App()->make(FetchContainersUpdatesFromYdPortalProcessor::class))->execute();
//    (App()->make(FetchDeliveryUpdatesFromYdPortalProcessor::class))->execute();
//    (App()->make(FetchPackingListFromVTPortalProcessor::class))->execute();
})->name('yd.refresh');

Route::get('/container/{reference}/refresh/', function (string $reference){
    $container = Container::where('reference', $reference)->first();
    $supplier = in_array($container->owner_id, [3, 4]) ? 'VT' : 'YD';

    $arrivalDates = PackingList::whereIn('reference', $container->packingLists->pluck('reference'))->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->get()->map(function($packingList){
        return $packingList->transports()->first()->drop_date;
    })->sortBy(function($date){
        return $date;
    });

    $startDate = $arrivalDates->first()->subDay()->format('d-m-Y');
    $endDate = $arrivalDates->last()->addDay()->format('d-m-Y');

    if($supplier === 'VT'){
        return (App()->make(FetchLoadedContainersFromVTPortalProcessor::class))->execute(Carbon::parse($endDate), Carbon::parse($endDate)->addDays(5));
    }

    if($supplier === 'YD'){
        return redirect(route('yd.refresh').'?start_date='.$startDate.'&end_date='.$endDate);
    }

})->name('container.refresh');

Route::get('/min_cbm', function (){
    $companies = CompanyModule::where('type', BusinessType::IMPORTER)->whereHas('orders', function ($query){
        return $query->whereHas('packingLists')->whereDoesntHave('packingLists', function($query){
            return $query->whereHas('packages', function($query){
                return $query->selectRaw('sum((width/100) * (height/100) * (length/100) * quantity) as cbm')->where('type', PackingListType::SHIPPING_PACKING_LIST)->where('status', '!=', 5)->having('cbm', '>', 0.3);
            });
        });
    })->limit(1)->get();

    $i = 0;
    foreach ($companies as $company) {
        $marking = $company->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
        echo '<a href="'.route('customer.profile', $marking).'" target="_blank">'.$i++.'. '.$marking.'</a><br>';
    }
});

Route::get('/warehouse', function () {
    return view('pages.warehouse');
})->name('warehouse');

Route::get('/warehouse/{id}/show', function ($id) {
    // $connection = CompanyConnection::where('invitee_reference', '2417MEN')->first();
    // $id = $connection->invitee->company->id;
    return view('pages.templates.warehouseDetails', ['id' => $id]);
})->name('warehouse.show');
Route::get('/export/customer-latest-order-date/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@export');
Route::get('/export/packing-list/{id}', 'Exports\ExportContainerPackingListController@export')->name('container.packaging_list.export');
Route::get('/export/pending-arrangement-delivery-list', 'Exports\ExportPendingArrangementPackingListV2Controller@export')->name('packaging_list.pending_arrangement.export');
// Route::get('/export/on-hold-packing-list', 'Exports\ExportPendingArrangementPackingListV2Controller@onHold')->name('packaging_list.on_hold.export');
Route::get('/export/on-hold-packing-list', 'Exports\ExportPendingArrangementPackingListController@onHold')->name('packaging_list.on_hold.export');
Route::get('/export/arrived-parcel', 'Exports\ExportArrivedParcelController@export')->name('packing_list.arrived_parcel.export');
Route::get('/export/parcel-summary', 'Exports\ExportArrivedParcelController@summary');
Route::get('/export/aging-list', 'Exports\ExportArrivedParcelController@aging')->name('aging-listing.export');
Route::get('/export/parcel-postcode', 'Exports\ExportParcelPostcodesController@export');
Route::get('/export/{year}/customer-total-order', 'Exports\ExportCustomersToExcelController@totalOrders');
Route::get('/export/packing-list-warehouse/guangzhou2-to-johor', 'Exports\ExportArrivedParcelController@guangZhou2ToJohor');

Route::get('/settings', function () {
    return view('pages.settings');
})->name('settings');
Route::get('/settings', function () {
    return view('pages.settings');
})->name('settings');

Route::get('/customer/{company_module_id}/summary', 'Exports\ExportCompanyModuleSummaryController@export')->name('customer.summary.export');
Route::get('/export-customer-order/{marking}', 'Exports\ExportCompanyModuleSummaryController@exportorderSummaryByMarking')->name('customer.orderSummary.export');

Route::get('/customer/summary/{year}/monthly', function ($year) {
    if (!in_array($year, [2022, 2023])) {
        return 'Year Error!';
    }

    // $containers = Container::whereMonth('loading_date', '>=', ((float)Carbon::now()->format('m') - 2))->whereYear('loading_date', (float)Carbon::now()->format('Y'))->get();

    if ($year == 2022) {
        $containers = Container::whereMonth('loading_date', '>=', 9)->whereYear('loading_date', 2022)->get();
    }

    if ($year == 2023) {
        $containers = Container::whereMonth('loading_date', '>=', 1)->whereYear('loading_date', 2023)->get();
    }

    $marking = '769SMC';
    $connection = CompanyConnection::where('invitee_reference', $marking)->first();
    $companyModuleId = $connection->invitee->id;
    foreach ($containers as $container){
        $packingLists = $container->packingLists()->get()->filter(function ($packingList) use ($companyModuleId){
            return $packingList->owner->company_module_id === $companyModuleId;
        });

        if (!count($packingLists)) continue;

        echo '<table style="width: 100%; text-align: center;">
          <tr>
            <th>Date</th>
            <th>Full Marking</th>
            <th>Container</th>
            <th>Description</th>
            <th>Ctns</th>
            <th>L (cm)</th>
            <th>H (cm)</th>
            <th>W (cm)</th>
            <th>CBM</th>
          </tr>';
        foreach ($packingLists as $packingList){
            if($packingList->packingLists->first()){
                $packingList = $packingList->packingLists->first();
            }
            $packages = $packingList->packages;
            foreach ($packages as $package){
                echo '<tr>
                        <td>'.$container->loading_date->format('d-m-Y').'</td>
                        <td>MS/CIEF/769SMC/'.$packingList->owner->owner->reference.'</td>
                        <td>'.$container->reference.'</td>
                        <td>'.$package->description.'</td>
                        <td>'.$package->quantity.'</td>
                        <td>'.$package->length.'</td>
                        <td>'.$package->height.'</td>
                        <td>'.$package->width.'</td>
                        <td>'.((($package->length / 100) * ($package->height / 100) * ($package->width / 100)) *  $package->quantity).'</td>
                      </tr>';
            }
        }
        echo '</table>';


    }

});

Route::get('/customers/active/{active_start}/{active_end}/{inactive_start?}/{inactive_end?}/{with_cbm?}', function ($active_start, $active_end, $inactive_start = null, $inactive_end = null, $with_cbm = false) {
    /* $activeCompanies = CompanyModule::where('type', BusinessType::IMPORTER)->whereHas('orderPackingLists', function($query) use($inactive_start, $inactive_end) {
         return $query->where('packing_lists.type', PackingListType::WAREHOUSE_RECEIVE_LIST)->whereHas('transports', function ($query) use ($inactive_start, $inactive_end) {
             return $query->where('drop_date', '>=', Carbon::parse($inactive_start))->where('drop_date', '<=', Carbon::parse($inactive_end)->addDay());
         });
     })->pluck('id');

     $companies = CompanyModule::where('type', BusinessType::IMPORTER)->whereHas('orderPackingLists', function($query) use($active_start, $active_end) {
         return $query->where('packing_lists.type', PackingListType::WAREHOUSE_RECEIVE_LIST)->whereHas('transports', function ($query) use ($active_start, $active_end) {
             return $query->whereDate('drop_date', '>=', Carbon::parse($active_start))->whereDate('drop_date', '<=', Carbon::parse($active_end)->addDay());
         });
     })->whereNotIn('id', $activeCompanies)->get();*/

    $companies = getActiveCompanies($inactive_start, $inactive_end, $active_start, $active_end);


    echo '<h4>List of customers active between <span style="color: green; font-weight: bold">'. Carbon::parse($active_start)->format('d/m/Y'). ' - '. Carbon::parse($active_end)->format('d/m/Y').'</span> & inactive between <span style="color: red; font-weight: bold">'. Carbon::parse($inactive_start)->format('d/m/Y'). ' - '. Carbon::parse($inactive_end)->format('d/m/Y').'</span></h4>';
    echo '<table>
          <tr>
            <th>#</th>
            <th>marking</th>
            <th>Number of Orders</th>
            <th>CBM</th>
          </tr>';
    foreach ($companies as $key => $company){
        $connection = $company->inviters()->withPivot('invitee_reference')->first();
        $marking = $connection ? $connection->pivot->invitee_reference:'';
        $packingList = collect();
        $totalCbm = 0;
        if($with_cbm){
            $packingList = $company->orderPackingLists()->where('packing_lists.type', PackingListType::SHIPPING_PACKING_LIST)->get();
            $totalCbm = $packingList->flatMap(function ($packingList) {
                return $packingList->packages;
            })->sum(function($package){
                return (( (float) $package->width / 100) * ( (float) $package->length / 100) * ( (float) $package->height / 100)) * $package->quantity;
            });
        }

        echo '<tr>
                        <td>'.$key.'</td>
                        <td><a href="'.route('customer.profile', $marking).'" target="_blank">'.$marking.'</a></td>
                        <td>'. $packingList->count() .'</td>
                        <td>'. $totalCbm .'</td>
                      </tr>';
    }
    echo '</table>';

});

Route::get('/online_payment/redirect', 'Billplz\CallbackBillplzController@callback')->name('online_payment.redirect');

Route::get('/order/{id}', function ($id) {
    return view('pages.orders.profile', ['id' => $id]);
})->name('order.details');

Route::get('/payment-and-billing', function () {
    return view('pages.paymentAndBilling');
})->name('admin.payment-and-billing');
Route::get('/notifications/list', 'Notifications\ListNotificationsController@list')->name('notifications.list');

Route::get('billplz/bills/{bill_no}', function($bill_no){
    return redirect(env('BILLPLZ_BASE_URL').'/bills/'.$bill_no);
 })->name('billplz.bill');

Route::get('/export/null-debtor/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@nullDebtor')->name('newDebtor.export');
Route::get('/export/payment-transactions/{section}/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@paymentTransactions')->name('paymentTransactions.export');

Route::get('/delayed_container/customers', function(){
    $containers = Container::whereHas('transports', function($query){
        return $query->whereHas('Schedules', function($query){
            return $query->where('etd', '>', Carbon::parse('15-10-2022'));
        });
    })->get();

    $orders = $containers->map(function($container){
        return $container->orders;
    })->flatten()->unique(function($order){
        return $order->company_module_id;
    });

    $companies = CompanyModule::whereIn('id', $orders->pluck('company_module_id'))->get();

    foreach ($companies as $company){
        $marking = $company->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
        echo '<a target="_blank" href="'.route('customer.profile', $marking).'">'.$marking.'</a><br>';
    }


});


Route::get('/container/billing/{month}/{year}', function($month, $year){
    $containers = Container::whereDate('loading_date', '>=', Carbon::parse('01-'.$month.'-'.$year))->whereDate('loading_date', '<', Carbon::parse('01-'.$month.'-'.$year)->addMonth())->get();

    $totalBillable = 0;
    $billed = 0;
    $totalBilled = 0;
    $totalPaid = 0;

    $basePrice = 315;
    $bigParcelDiscount = -15;

    $yiwuCost = 15;

    $discount = -20;
    $yiwuDiscount = -45;

    $outstationStates = [8, 3, 16, 10];


    foreach($containers as $container) {
        $containerTotalBillable = 0;
        $containerBilled = 0;
        $containerTotalBilled = 0;
        $containerTotalPaid = 0;
        $containerCost = 0;

        $packingLists = $container->packingLists;

        $totalBillable += count($packingLists);
        $containerTotalBillable += count($packingLists);
        echo '<h3>'.$container->reference.' ('.$container->loading_date->format('d-m-Y').')</h3>';

        foreach ($packingLists as $packingList) {
            $invoice = $packingList->transactions()
                ->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
                ->first();


            $warehouseList = PackingList::where('reference', $packingList->reference)->where('type', 1)->first();
            if($warehouseList){
                $packing_list_drop_date = $warehouseList->transports->first()->drop_date;
            } else {
                echo '<------------- can\'t find arrival date -------------->';
            }

            $order = $packingList->owner;
            $address = $order->addresses()->where('status', ApprovalStatus::APPROVED)->first();
            $warehouseId = $order->orderRoles()->where('role_id', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->company_module_id;

            $cbm = round($packingList->packages->where('type', '!=', PackageType::OVER_WEIGHT)->sum(function($package) {
                return ($package->width / 100) * ($package->height / 100) *($package->length / 100) * ($package->quantity);
            }), 2);

            $over_weight_cbm = round($packingList->packages->where('type', PackageType::OVER_WEIGHT)->sum(function($package) {
                return ($package->width / 100) * ($package->height / 100) *($package->length / 100) * ($package->quantity);
            }), 2);
            $price = $basePrice;

            if($warehouseId === 2358){
                $price += $yiwuCost;
                if($packing_list_drop_date >= Carbon::parse('19-9-2022')){
                    $price += $yiwuDiscount;
                }
            } else {
                if($cbm >= 2 && in_array($address->state_id, [4, 15])){
                    $price += $bigParcelDiscount;
                }
                if($packing_list_drop_date >= Carbon::parse('19-9-2022')){
                    $price += $discount;
                }
            }

            if(in_array($address->state_id,$outstationStates)) {
                $price += 50;
            }

            $cbm = max($cbm, 0.3);
            $cost = $price * ($cbm + $over_weight_cbm);

            $containerCost += $cost;

            if(in_array($address->state_id, [13, 14])) {
                echo 'East Malaysia - ';
            }
            echo 'estimated cost: [QTY: '.($cbm + $over_weight_cbm).' | Unit Price: '.$price.' | Total: '.$cost.']';
            echo '<br>';

            if(!$invoice) {
                echo '<p style="color: red"><a href="'.route('order.show', $order->reference).'" target="_blank">'.$packingList->reference .'</a> Warning: no billing</p>';
                continue;
            }

            $payments = $invoice->transactions()
                ->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
                ->get();

            $billed += 1;
            $containerBilled += 1;

            $totalBilled += $invoice->amount;
            $containerTotalBilled += $invoice->amount;

            $totalPaid += $payments->sum('amount');
            $containerTotalPaid += $payments->sum('amount');

            echo '<span style="color: '.(($invoice->amount - $payments->sum('amount')) < 0.01 ? 'green' : 'red').'"><p style="color: red"><a href="'.route('order.show', $order->reference).'" target="_blank">'.$packingList->reference .'</a> | Amount: '.$invoice->amount.' | Paid: '.$payments->sum('amount').' | Invoice Date: '.$invoice->created_at->format('d-m-Y'). (($invoice->amount - $payments->sum('amount')) < 0.01 ? '' : '('.$invoice->created_at->diffForHumans().')').'</span>';
            echo '<br><br>';

        }

        echo '<h4>Container Invoices: '.$containerBilled.'/'.$containerTotalBillable.'</h4>';
        echo '<h4>Billed Total: '.$containerTotalBilled.'</h4>';
        echo '<h4>Total Paid: '.$containerTotalPaid.'</h4>';
        echo '<h4>Outstanding: '.($totalBilled - $containerTotalPaid).'</h4>';
        echo '<h4>Estimated Cost: '.$containerCost.'</h4>';
        echo '<br><br><br>';
    }

    echo '<h2>Total Invoices: '.$billed.'/'.$totalBillable.'</h2>';
    echo '<h2>Billed Total: '.$totalBilled.'</h2>';
    echo '<h2>Total Paid: '.$totalPaid.'</h2>';
    echo '<h2>Outstanding: '.($totalBilled - $totalPaid).'</h2>';

});

Route::get('/yd/fix', function(){
    $packingLists = PackingList::where('type', PackingListType::SHIPPING_PACKING_LIST)->where('status', ApprovalStatus::APPROVED)->where('claimant_id', 2307)->get();
    $i = 0;
    echo count($packingLists).'<br><br>';
    foreach ($packingLists as $packingList){
        try {
            (App()->make(UpdateDoFromYDPortalProcessor::class))->execute($packingList);
            echo 'success'.'<br>';
        } catch (Exception $exception){
            echo '<span style="color:red;">'.$packingList->reference.'</span>';
        }

    }
});

Route::get('/billplz/fix', function(){
    $payments = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->get();
    echo '<h3>fixed orders</h3>';
    foreach ($payments as $payment){
        $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$payment->payment_reference);

        if($response->successful()){
            $data = $response->json();
            $invoice = $payment->owner;
            if(!$invoice){
                continue;
            }
            $packingList = $invoice->owner;
            $order  = $packingList->owner;

            $orderNumber = $order->reference;
            if(!$data['paid'] && $payment->status === ApprovalStatus::APPROVED) {
                echo '<br><span style="color: red">Fraude: <a href="'.route('order.show', $orderNumber).'" target="_blank">'.$orderNumber.'</a></span><br>';
                continue;
            }

            if($data['paid']){
                if($payment->status !== ApprovalStatus::APPROVED){
                    echo '<a href="'.route('order.show', $orderNumber).'" target="_blank">'.$orderNumber.'</a><br>';
                }
                $payment->status = ApprovalStatus::APPROVED;
                $payment->save();

                $invoice->status = ApprovalStatus::COMPLETED;
                $invoice->save();

                $packingList = $payment->owner->owner;
                if(app()->environment('production')){
                    try {
                        (App()->make(UpdateDoFromVTPortalProcessor::class))->execute($packingList);
                        (App()->make(UpdateDoFromYDPortalProcessor::class))->execute($packingList);
                    } catch (Exception $exception){
                        echo '<br><span style="color: red">Malformed Address: <a href="'.route('order.show', $orderNumber).'" target="_blank">'.$orderNumber.'</a></span><br>';
                    }
                }
            }
        }else{
           echo "billplz error";
        }

    }
});


Route::get('/invoices/fix/{company_module_id}', function($company_module_id) {

    $orders = Order::whereIn('company_module_id', json_decode($company_module_id))->get();

    foreach ($orders as $order){
        $invoices = $order->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->get();
        foreach ($invoices as $invoice){

            $invoice->documents()->delete();

            $transaction_invoice_pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoice', ['invoice_transaction' => $invoice]);

            $document_object = new DocumentObject(
                DocumentType::SHIPPING_INVOICE,
                [chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
                '',
                ApprovalStatus::COMPLETED,
                'shipping_invoice'
            );

            /** @var Document $document */
            $document = (App()->make(CreatesDocument::class))->execute($invoice, $document_object);

            (App()->make(CreatesFiles::class))->execute($document, $document_object);

            dump($document);
        }
    }

});

Route::get('/invoices/combine/{ids}', function($ids){

    $ids = json_decode($ids);

    $transactions = Transaction::whereIn('id', $ids)->get();

    $pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoices_combined', ['invoice_transactions' => $transactions]);
    return $pdf->download('combined_invoice_.pdf');
})->name('invoice.combined_summary');

// Route::get('/generate/invoices', function(){
//     $packingLists = (App()->make(ListsPackingLists::class))->execute(['does_not_have_transaction_type' => 1, 'type' => 2]);
//     foreach ($packingLists as $packingList){
//         $order = $packingList->owner;
//         if(!($order instanceof Order)) {
//             echo '<span style="color: red;">failed to generate...</span><br>';
//             continue;
//         }

//         $companyModule = $order->companyModule;
//         $billingAddress = $companyModule->addresses()->where('type', \App\Classes\ValueObjects\Constants\AddressType::BILLING)->first();
//         $deliveryAddress = $order->addresses()->where('status', ApprovalStatus::APPROVED)->first();

//         $postCodes = \App\Models\SegmentConstant::whereIn('reference', ['CENTER_POSTCODE', 'OUTSTATION_POSTCODE'])->get()->pluck('value')->flatten();

//         if(!!$billingAddress && in_array($deliveryAddress->postcode, $postCodes->toArray())){
//             try {
//                 (App()->make(CreateInvoiceTransactionProcessor::class))->execute($packingList);
//                 echo '<span style="color: green;">Invoice Generated...</span><br>';

//             } catch (Exception $exception){
//                 echo '<span style="color: red;">failed to generate...</span><br>';
//             }
//         }
//         echo '<span style="color: red;">failed to generate...</span><br>';
//     }
// })->name('generate.invoices');

Route::get('/invoices/approve', function(Request $request){
    $invoices = Transaction::where('type', TransactionType::SHIPPING_INVOICE)->where('status', ApprovalStatus::PENDING_SUBMISSION)->get();

    foreach ($invoices as $invoice) {
        $packingList = $invoice->owner;
        if (!$packingList) {
            dump ('Error packingList not found. Invoice ID - ' . $invoice->id);
            continue;
        }
        $order = $packingList->owner;

        if ($request->input('exclude')){
            if(in_array($order->reference, json_decode($request->input('exclude')))){
                continue;
            }
        }

        try {
            (App()->make(ApproveShippingInvoiceTransactionProcessor::class))->execute($packingList);
            echo '<span style="color: green;">Invoice Approved...</span><br>';

        } catch (Exception $exception){
            echo '<span style="color: red;">failed to approve...</span><br>';

        }
    }


})->name('invoices.approve');

Route::get('/invoices/show-duplicated', function(Request $request){
    $transactionWithMultipleInvoice = DB::table('transactions')
        ->where('type', TransactionType::SHIPPING_INVOICE)
        ->whereNotIn('status', [ApprovalStatus::EXPIRED, ApprovalStatus::SUSPENDED])
        ->where('deleted_at', null)
        ->select('owner_id', DB::raw('count(*) as count'))
        ->groupBy('owner_id')
        ->having('count', '>', 1)
        ->get();

    echo 'Total Duplicates: ' . count($transactionWithMultipleInvoice) . '<br>';

    $duplicatedOrderId = [];
    $duplicatedOrderArray = [];
    foreach($transactionWithMultipleInvoice as $invoice) {
        $duplicatedOrderId[] = $invoice->owner_id;
        $duplicatedOrderArray[$invoice->owner_id] = $invoice->count;
    }

    $duplicatedInvoice = Transaction::whereIn('owner_id', $duplicatedOrderId)->orderByDesc('owner_id')->get();
    echo '<br>';
    echo '<table>';
    echo "<tr>";
    echo "<td style='border:1px solid'>Order Reference</td>";
    echo "<td  style='border:1px solid'>Status</td>";
    echo "<td  style='border:1px solid'>Invoice Owner ID</td>";
    echo "<td  style='border:1px solid'>Amount</td>";
    echo "<td  style='border:1px solid'>Count</td>";
    echo "</tr>";

    foreach($duplicatedInvoice as $invoice) {
        $order = $invoice->owner->owner;

        $billplzPaymentId = '';

        if ($invoice->status == ApprovalStatus::COMPLETED) {
            if ($invoice->transactions->first()->type == TransactionType::PAYMENT) {
                $billplzPaymentId = $invoice->transactions->first()->payment_reference ;
            }
        }

        echo "<tr>";
        echo '<td style="border:1px solid"><a target="_blank" href="'.route('order.show', $order->reference).'">'. $order->reference.' - </a>' . $order->created_at . '</td>';
        echo "<td style='border:1px solid'>".ApprovalStatus::APPROVAL_STATUS_ID[$invoice->status]. ' Billplz reference: ' . $billplzPaymentId . "</td>";
        echo "<td style='border:1px solid'>$invoice->owner_id</td>";
        echo "<td style='border:1px solid'>$invoice->amount</td>";
        echo "<td style='border:1px solid'>".$duplicatedOrderArray[$invoice->owner_id]."</td>";
        echo "</tr>";
    }
    echo '</table>';
});

Route::get('/invoices/delete-duplicated', function(Request $request){
    $duplicatedInvoices = DB::table('transactions')
        ->where('type', TransactionType::SHIPPING_INVOICE)
        ->where('status', '!=' , ApprovalStatus::EXPIRED)
        ->where('deleted_at', null)
        ->select('owner_id', DB::raw('count(*) as count'))
        ->groupBy('owner_id')
        ->having('count', '>', 1)
        ->get();

    $duplicatedInvoices = Transaction::whereIn('owner_id', $duplicatedInvoices->pluck('owner_id'))->get()->groupBy('owner_id');

    foreach($duplicatedInvoices as $invoice) {
        $packingList = $invoice->first()->owner;
        $order = $packingList->owner;

        $paidInvoice = $packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->where('status', ApprovalStatus::COMPLETED)->get();

        // if have completed invoice (verified payment)
        if (count($paidInvoice)) {
            $packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->where('status', '!=', ApprovalStatus::COMPLETED)->delete();
            continue;
        } else {
            dump($order->reference . ' -no');
        }

        // if have unverified payment
        // $paymentHistory = $packingList->transactions()->whereHas('transactions', function($query){
        //     return $query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION ,ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]);
        // })->get();
        // if (count($paymentHistory)) {
        //     $packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->where('id', '!=', $paymentHistory->first()->id)->delete();
        //     continue;
        // }

        // // delete duplicated invoices
        // $unpaidInvoices = $packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->orderBy('id', 'desc')->get();

        // $unpaidInvoicesIds = $unpaidInvoices->pluck('id')->toArray();
        // array_shift($unpaidInvoicesIds);
        // Transaction::whereIn('id', $unpaidInvoicesIds)->delete();

        // // delete expired invoices
        // $packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->where('status', '!=', ApprovalStatus::EXPIRED)->delete();

        // // delete suspended invoices
        // $suspendedInvoices = $packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->where('status', '!=', ApprovalStatus::SUSPENDED)->orderBy('id', 'desc')->get();
        // $suspendedInvoicesIds = $suspendedInvoices->pluck('id')->toArray();
        // array_shift($suspendedInvoicesIds);
        // Transaction::whereIn('id', $suspendedInvoicesIds)->delete();
    }
});

Route::get('/packing-lists/show-duplicated', function(Request $request){
    $results = PackingList::select('reference', 'type', DB::raw('count(*) as total'))
            ->groupBy('reference', 'type')
            ->having('total', '>', 1)
            ->get()
            ->toArray();

    echo '<table>';
    echo "<tr>";
    echo "<td style='border:1px solid'>reference</td>";
    echo "<td  style='border:1px solid'>type</td>";
    echo "<td  style='border:1px solid'>count</td>";
    echo "</tr>";

    foreach($results as $result) {
        // dd($result);
        echo "<tr>";
        echo "<td style='border:1px solid'>" . $result['reference'] . "</td>";
        echo "<td style='border:1px solid'>" . $result['type'] . "</td>";
        echo "<td style='border:1px solid'>" . $result['total'] . "</td>";
        echo "</tr>";
    }
    echo '</table>';
});

Route::get('/packing-lists/delete-duplicated', function(Request $request){
    $results = PackingList::select('reference', 'type', DB::raw('count(*) as total'))
        ->groupBy('reference', 'type')
        ->having('total', '>', 1)
        ->get()
        ->toArray();

    foreach($results as $result) {
        $duplicatedPackingList = PackingList::where('reference', $result['reference'])->where('type', $result['type'])->orderBy('id', 'desc')->get();

        // if packinglist has paid inivoice
        $paidPackinglist = PackingList::where('reference', $result['reference'])->where('type', $result['type'])->whereHas('transactions', function($query){
            return $query->where('type', TransactionType::SHIPPING_INVOICE)->where('status', ApprovalStatus::COMPLETED);
        })->get();

        if (count($paidPackinglist)) {
            // delete all the other packing list
            $paidPackinglistID = $paidPackinglist->first()->id;
            $duplicatedPackingList = PackingList::where('reference', $result['reference'])->where('type', $result['type'])->where('id', '!=', $paidPackinglistID)->get();
            // $duplicatedPackingList->delete();
            foreach ($duplicatedPackingList as $p) {
                $p->delete();
                dump('have paid packinglist, deleting id:' . $p->id);
            }
        } else {
            // delete all but left the latest packing list
            $firstItem = $duplicatedPackingList->shift();
            // dump('dont have paid packinglist, keep first and delete others');
            foreach ($duplicatedPackingList as $p) {
                $p->delete();
                dump('dont have paid packinglist, keep latest id:' . $firstItem->id . ', and deleting id:' . $p->id);
            }
        }
    }
});

Route::get('/wallet/{marking}/details', function ($marking) {
    $connection = CompanyConnection::where('invitee_reference', $marking)->first();
    $id = $connection->invitee->id;
    return view('pages.wallet.index', ['id' => $id, 'marking' => $marking]);
})->name('wallet.details');

Route::get('/wallet/{wallet_id}/{is_precise}/export', 'Exports\ExportCustomersWalletTransactionToExcelController@export')->name('wallet.details-export');

Route::get('/wallet/audit', function (Request $request) {
    $wallets = \App\Models\Wallet::all();

    $i = 0;
    foreach ($wallets as $wallet){
        $topups = 0;
        $credit = 0;
        $payments = 0;
        $debit = 0;

        foreach ($wallet->transactions as $transaction){
            if(!in_array((int) $transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) continue;
            if((int) $transaction->type === TransactionType::TOP_UP || (int) $transaction->type === TransactionType::GROUP_PAYMENT) {
            // if((int) $transaction->type === TransactionType::TOP_UP) {
                $topups += (float) $transaction->amount;
            }
            if((int) $transaction->type === TransactionType::CREDIT_NOTE) $credit += (float) $transaction->amount;
            if((int) $transaction->type === TransactionType::PAYMENT) $payments += (float) $transaction->amount;
            if((int) $transaction->type === TransactionType::DEBIT_NOTE) $debit += (float) $transaction->amount;
        }
        if((round((float) $wallet->amount - (($topups + $credit) - ($payments + $debit)), 2) == 0) AND $wallet->amount > -0.01) continue;

        $i++;

        echo $i.". Marking: ". $wallet->owner->connections->first()->invitee_reference ."(".$wallet->id.")<br>Current Balance: ". $wallet->amount ."<br>Audit Balance: ". (($topups + $credit) - ($payments + $debit)) ."<br>Difference: ". round((float) $wallet->amount - (($topups + $credit) - ($payments + $debit)), 2) ."<br><br><br>";
    }
});

Route::get('/final-duplicated-invoice-debug', function(){
    $duplicatedTransactions = Transaction::select(DB::raw('owner_type, owner_id, receiver, type, GROUP_CONCAT(id) as transaction_ids, COUNT(*) as count'))
    ->whereNotIn('status', [ApprovalStatus::REJECTED,ApprovalStatus::SUSPENDED,ApprovalStatus::EXPIRED])
    ->groupBy('owner_type', 'owner_id', 'receiver', 'type')
    ->having('count', '>', 1)
    ->get();

    $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID;

    $transactionType = TransactionType::TRANSACTION_TYPE_ID;

    echo '<table style="width: 100%; text-align: center; border: 1px solid black">
    <tr>
      <!-- <th style="border: 1px solid black" >Owner Type</th> -->
      <!-- <th style="border: 1px solid black" >Owner Id</th> -->
      <!--<th style="border: 1px solid black" >Reveiver</th>-->
      <th style="border: 1px solid black" >Order</th>
      <th style="border: 1px solid black" >Transaction type</th>
      <th style="border: 1px solid black" >Count</th>
      <th style="border: 1px solid black" >Invoice Ids</th>
      <th style="border: 1px solid black" >Invoices</th>
    </tr>';

    foreach ($duplicatedTransactions as $transaction) {
        $transactionIds = explode(',', $transaction->transaction_ids);

        $duplicatedInvoice = Transaction::whereIn('id', $transactionIds)->get();

        $order_reference = $duplicatedInvoice->first()->owner->owner->reference ?? null;

        if ($transaction->type == TransactionType::PAYMENT) {
            $order_reference = $duplicatedInvoice->first()->owner->owner->owner->reference ?? null;
        }

        echo '<tr>';
            // echo '<td style="border: 1px solid black">' . $transaction->owner_type . '</td>';
            // echo '<td style="border: 1px solid black">' . $transaction->owner_id . '</td>';
            echo '<td style="border: 1px solid black">' . $transaction->receiver . '</td>';
            echo '<td style="border: 1px solid black">' . '<a target="_blank" href="'.route('order.show', $order_reference).'">'. $order_reference .'</a>' . '</td>';
            echo '<td style="border: 1px solid black">' . $transactionType[$transaction->type] . '</td>';
            echo '<td style="border: 1px solid black">' . count($transactionIds) . '</td>';
            echo '<td style="border: 1px solid black; text-align: left">';
            foreach ($duplicatedInvoice as $invoice) {
                echo '<p>ID: ' . $invoice->id . '. Status: ' . $approvalStatusArray[$invoice->status] . '. Amount: ' . $invoice->amount . '</p>';
            }
            echo'</td>';
        echo '</tr>';
    }
    echo '</table>';
});


Route::get('/duplicate-package-clean-up', function(){
    // Fetching duplicate rows based on given columns
    $duplicates = Package::select('packing_list_id', 'description', 'width', 'height', 'weight', 'quantity', DB::raw('COUNT(*) as count'))
        ->groupBy('packing_list_id', 'description', 'width', 'height', 'weight', 'quantity')
        ->havingRaw('COUNT(*) > 1')
        ->get();

    $totalGroups = 0;

    // Loop through each group of duplicates
    foreach ($duplicates as $duplicate) {
        $totalGroups++;

        // Fetch all rows of the current group and order by created_at
        $rows = Package::where('packing_list_id', $duplicate->packing_list_id)
            ->where('description', $duplicate->description)
            ->where('width', $duplicate->width)
            ->where('height', $duplicate->height)
            ->where('weight', $duplicate->weight)
            ->where('quantity', $duplicate->quantity)
            ->orderBy('created_at')
            ->get();

        // Echo the group details
        echo "Group {$totalGroups} Details:<br>";
        foreach ($rows as $row) {
            echo "ID: {$row->id}, Packing List ID: {$row->packing_list_id}, Description: {$row->description}, Width: {$row->width}, Height: {$row->height}, Weight: {$row->weight}, Quantity: {$row->quantity}, Created At: {$row->created_at}<br>";
        }
        // Delete all rows in the group except the first one (oldest based on created_at)
        $firstRow = $rows->shift();
        foreach ($rows as $row) {
            Package::where('id', $row->id)->delete();
        }

        // Calculate the case age for the group (assuming case age means difference between current date and created_at of the oldest row)
        $caseAge = Carbon::now()->diffInDays(Carbon::parse($firstRow->created_at));
        echo "Case Age for Group {$totalGroups}: {$caseAge} days<br><br>";
    }

    // Echo the total number of duplicate groups
    echo "Total Number of Duplicate Groups: {$totalGroups}";

});

Route::get('/feedback/{token}', function ($token) {
    return view('pages.feedback.customer', ['token' => $token]);
})->name('feedback.customer');


Route::get('/feedback', function () {
    return view('pages.feedback');
})->name('admin.feedback');

Route::get('/export/feedback', 'Exports\ExportFeedbackDataController@export')->middleware(['api'])->middleware(['valid.token'])->name('feedback.export');

Route::get('/404', function () {
    abort(404);
})->name('error.404');

Route::get('transaction/{id}/credit_note/download', 'Transactions\GenerateCreditNotePdfController@download')->name('transaction.credit_note.download');

Route::get('/wallets/active', function(){
    $wallets = Wallet::all();

    echo '<table>';
    foreach ($wallets as $wallet){
        $companyMarking = $wallet->owner->getMarking();
        echo '<tr>';
        echo '<td><a href="'.route('wallet.details', $companyMarking).'" target="_blank">'.$companyMarking.'</a>'."(".$wallet->id.")".'</td>';
        echo '<td>'.$wallet->amount.'</td>';
        echo '</tr>';
    }
    echo '</table>';
});

Route::get('fix-payment-status-updated-but-failed-update-invoice', function (UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor) {
    $invoices = Transaction::where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [2])
        ->whereHas('transactions', function ($query) {
            $query->where('type', TransactionType::PAYMENT)
                ->whereIn('status', [2, 3]);
        })->get();


    foreach ($invoices as $invoice) {
        echo "Fixing" . $invoice->owner->owner->reference . '<br>';

        $totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');

        if (($invoice->amount - $totalPaidAmount) < 0.01) {
            $updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
            $packingList = $invoice->owner;
            $packingList->status = ApprovalStatus::APPROVED;
            $packingList->save();

            if (app()->environment('production')) {
                $updateDoFromVTPortalProcessor->execute($packingList);
                $updateDoFromYDPortalProcessor->execute($packingList);
            }

            echo 'done fix ' . $invoice->owner->owner->reference . '<br>';
        }
    }
});

//A page to monitor Experimental solution (Vue Polling) to solve an AWS API Gateway problem limitation for Laravel Vapor in the event of a emergency rollback to Google
Route::get('/payment-and-billing-2', function () {
    return view('pages.paymentAndBilling2');
})->name('admin.payment-and-billing-2');
