<?php

namespace App\Classes\Modules\Orders\ControllersLogic;


use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Orders\Services\CalculatesCBM;
use App\Classes\Modules\Orders\Services\CalculatesBaseRate;
use App\Classes\Modules\Orders\Services\CalculatesSegmentRate;
use App\Classes\Modules\Orders\Services\CalculatesStateRate;
use App\Classes\Modules\Orders\Services\CalculatesWarehouseRate;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\Modules\Transactions\Processors\CreateShippingCostTransactionProcessor;

use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Http\Resources\OrderResource;
use App\Models\Order;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ShippingCostLogic extends AbstractControllerLogic
{


    /**
     * @return array
     */
    protected function notification():array {
        return [
            'title' => 'Order Shipping Cost',
            'message' => 'Order shipping cost calculation done'
        ];
    }

    /** @var CalculateCBM */
    private $calculateCBM;

    /** @var CalculatesBaseRate */
    private $calculateBaseRate;

    /** @var CalculatesSegmentRate */
    private $calculateSegmentRate;

    /** @var CalculatesStateRate */
    private $calculateStateRate;

    /** @var CalculatesWarehouse */
    private $calculateWarehouseRate;

    /** @var FetchesOrder */
    private $fetchesOrder;

    /** @var ShippingCostTransactionProcessor */
    private $shippingCostTransactionProcessor;

    /**
     * ShippingCostLogic constructor.
     * @param CalculateCBM $calculateCBM
     * @param FetchesOrder $fetchesOrder
     */
    public function __construct(FetchesOrder $fetchesOrder, CalculatesCBM $calculateCBM, CalculatesBaseRate $calculateBaseRate, CalculatesSegmentRate $calculateSegmentRate, CalculatesStateRate $calculateStateRate, CalculatesWarehouseRate $calculateWarehouseRate, CreateShippingCostTransactionProcessor $shippingCostTransactionProcessor)
    {
        $this->fetchesOrder = $fetchesOrder;
        $this->calculateCBM = $calculateCBM;
        $this->calculatesBaseRate = $calculateBaseRate;
        $this->calculatesSegmentRate = $calculateSegmentRate;
        $this->calculatesStateRate = $calculateStateRate;
        $this->calculateWarehouseRate = $calculateWarehouseRate;
        $this->shippingCostTransactionProcessor = $shippingCostTransactionProcessor;
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Classes\Exceptions\MalformedRequestException
     */
    public function logic(Request $request) : JsonResponse
    {
        $order = $this->fetchesOrder->getRepository()->where(['id' => $request->route('id')])->first();

        $baseRate = $this->calculatesBaseRate->execute($order);
        $segmentRate = $this->calculatesSegmentRate->execute($order, SegmentConstants::STANDARD_SEGMENT) + $this->calculatesSegmentRate->execute($order, SegmentConstants::CUSTOM_SEGMENT);
        $stateRate = $this->calculatesStateRate->execute($order, false) + $this->calculatesStateRate->execute($order, true);
        $warehouseRate = $this->calculateWarehouseRate->execute($order);

        $totalShippingCost = 0;
        $totalCBM = 0;
        $quantity = 0;
        foreach($order->parcels as $parcel){
            $cbm = $this->calculateCBM->execute($order, $parcel);

            if($cbm > 0){
                $totalCBM += $cbm;
                $quantity ++;
                $totalShippingCost += (($segmentRate + $stateRate + $warehouseRate) * $cbm);
            }
        }

        $this->shippingCostTransactionProcessor->execute($order, $quantity, round($totalCBM,2), round($totalShippingCost,2));
        return $this->resourceResponse(new OrderResource($order));
    }

}
