<?php

namespace Lc\CaracoleBundle\Generator;

use App\Solver\Order\OrderShopSolver;
use Lc\CaracoleBundle\Definition\SectionSettingDefinition;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\Section\SectionModel;
use Lc\SovBundle\Solver\Setting\SettingSolver;

class OrderReferenceGenerator
{
    protected SettingSolver $settingSolver;
    protected OrderShopSolver $orderShopSolver;

    public function __construct(SettingSolver $settingSolver, OrderShopSolver $orderShopSolver)
    {
        $this->settingSolver = $settingSolver;
        $this->orderShopSolver= $orderShopSolver;
    }

    public function buildReference(OrderShopInterface $orderShop): string
    {
        $complementaryIndex = null;

        if ($orderShop->getMainOrderShop()) {
            $complementaryIndex = 0;
            foreach ($orderShop->getMainOrderShop()->getComplementaryOrderShops() as $complementaryOrder) {
                if ($this->orderShopSolver->isValid($complementaryOrder)) $complementaryIndex++;
            }
            $orderShop = $complementaryOrder->getMainOrderShop();
        }

        switch ($orderShop->getSection()->getCycleType()) {
            case SectionModel::CYCLE_TYPE_DAY:
                $reference =  $this->buildReferenceCycleDay($orderShop);
                break;
            case SectionModel::CYCLE_TYPE_WEEK:
                $reference =  $this->buildReferenceCycleWeek($orderShop,);
                break;
            case SectionModel::CYCLE_TYPE_MONTH:
                $reference = $this->buildReferenceCycleMonth($orderShop);
                break;
            case SectionModel::CYCLE_TYPE_YEAR:
                $reference =  $this->buildReferenceCycleYear($orderShop);
                break;
            default:
                $reference = 'C' . $orderShop->getId();
                break;
        }

        if($complementaryIndex) {
            $reference = $reference.'C'.$this->numberPad($complementaryIndex, 1);
        }

        return $reference;
    }

    public function buildReferenceCycleDay(OrderShopInterface $orderShop): string
    {
        return $this->getPrefixReference($orderShop) .
                'J' . $orderShop->getDistribution()->getCycleNumber() .
                'C' . $this->numberPad($orderShop->getCycleId(), 3) .
                'A' . $this->formatYear($orderShop->getDistribution()->getYear());
    }

    public function buildReferenceCycleWeek(OrderShopInterface $orderShop): string
    {
        return $this->getPrefixReference($orderShop) .
                'S' . $orderShop->getDistribution()->getCycleNumber() .
                'C' . $this->numberPad($orderShop->getCycleId(), 4) .
                'A' . $this->formatYear($orderShop->getDistribution()->getYear());
    }

    public function buildReferenceCycleMonth(OrderShopInterface $orderShop): string {
        return $this->getPrefixReference($orderShop) .
                'M' . $orderShop->getDistribution()->getCycleNumber() .
                'C' . $this->numberPad($orderShop->getCycleId(), 4) .
                'A' . $this->formatYear($orderShop->getDistribution()->getYear());
    }

    public function buildReferenceCycleYear(OrderShopInterface $orderShop): string
    {
        return $this->getPrefixReference($orderShop) .
                'C' . $this->numberPad($orderShop->getCycleId(), 5) .
                'A' . $this->formatYear($orderShop->getDistribution()->getYear());
    }

    public function getPrefixReference(OrderShopInterface $orderShop): string
    {
        return ''.$this->settingSolver->getSettingValue(
                $orderShop->getSection(),
                SectionSettingDefinition::SETTING_REFERENCE_PREFIX
        );
    }

    protected function numberPad($number, $length): string
    {
        return str_pad($number, $length, "0", STR_PAD_LEFT);
    }

    protected function formatYear(int $year):int{
        return substr($year, -2);
    }

}