<?php

namespace common\logic\Distribution\Distribution\Export;

use common\helpers\CSV;
use common\logic\AbstractGenerator;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Repository\OrderRepository;
use common\logic\Order\Order\Service\OrderBuilder;
use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Order\ProductOrder\Service\ProductOrderSolver;
use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\PointSale\PointSale\Repository\PointSaleRepository;
use common\logic\Producer\Producer\Service\ProducerSolver;
use common\logic\Product\Product\Service\ProductSolver;

class DistributionReport2CsvGenerator extends AbstractGenerator implements DistributionExportGeneratorInterface
{
    protected ProductSolver $productSolver;
    protected OrderRepository $orderRepository;
    protected OrderSolver $orderSolver;
    protected PointSaleRepository $pointSaleRepository;
    protected OrderBuilder $orderBuilder;
    protected ProducerSolver $producerSolver;
    protected ProductOrderSolver $productOrderSolver;

    public function loadDependencies(): void
    {
        $this->productSolver = $this->loadService(ProductSolver::class);
        $this->orderRepository = $this->loadService(OrderRepository::class);
        $this->orderSolver = $this->loadService(OrderSolver::class);
        $this->pointSaleRepository = $this->loadService(PointSaleRepository::class);
        $this->orderBuilder = $this->loadService(OrderBuilder::class);
        $this->producerSolver = $this->loadService(ProducerSolver::class);
        $this->productOrderSolver = $this->loadService(ProductOrderSolver::class);
    }

    public function generate(Distribution $distribution, bool $save = false)
    {
        $datas = [['Distribution du '.date('d/m/Y', strtotime($distribution->date))]];
        $ordersArray = $this->orderRepository->findOrdersByDistribution($distribution);
        $pointsSaleArray = $this->pointSaleRepository->findPointSales();
        foreach ($pointsSaleArray as $pointSale) {
            $this->orderBuilder->initPointSaleOrders($pointSale, $ordersArray);
        }

        foreach($pointsSaleArray as $pointSale) {
            if(count($pointSale->orders)) {
                foreach($this->addOrder($pointSale->orders[0], $pointSale) as $line) {
                    $datas[] = $line;
                }
                foreach($pointSale->orders as $key => $order) {
                    if ($key !== array_key_first($pointSale->orders)) {
                        foreach($this->addOrder($order) as $line) {
                            $datas[] = $line;
                        }
                    }
                }
            }
        }

        CSV::send('Commandes.csv', $datas);
    }

    public function addOrder(Order $order, PointSale $pointSale = null)
    {
        $datas = [];

        if(isset($order->productOrder[0])) {
            $firstProductOrder = $order->productOrder[0];
            $datas[] = [
                $pointSale ? $pointSale->name : '',
                $this->orderSolver->getOrderUsername($order),
                CSV::formatNumber($this->productOrderSolver->getQuantityPriorityPieces($firstProductOrder)),
                $this->productSolver->getNameExport($firstProductOrder->product),
                $this->productSolver->getWeightAsString($firstProductOrder->product),
                $this->orderSolver->hasPhone($order) ? CSV::formatPhone($this->orderSolver->getPhone($order)) : '',
                $this->orderRepository->getPaymentLabelPaid($order),
                CSV::formatNumber($this->orderSolver->getOrderAmountWithTax($order))
            ];

            foreach($order->productOrder as $key => $productOrder) {
                if ($key !== array_key_first($order->productOrder)) {
                    $datas[] = [
                        '',
                        '',
                        CSV::formatNumber($this->productOrderSolver->getQuantityPriorityPieces($productOrder)),
                        $this->productSolver->getNameExport($productOrder->product),
                        $this->productSolver->getWeightAsString($productOrder->product),
                    ];
                }
            }
        }

        return $datas;
    }
}