<?php

namespace Podeli\Payment\Models;

class Order extends Entity
{
    public function __construct()
    {
        $this->data = [
            'amount'            => 0.0,
            'items'             => [],
            'prepaidAmount'     => 0.0,
        ];
    }

    public function setId(string $id)
    {
        $id = $this->prepareOrderId($id);
        $this->data['id'] = $id;
        return $this;
    }

    public function getId()
    {
    	return $this->data['id'];
    }

    public function disableTwoStagePayment()
    {
        $this->data['isTwoStagePayment'] = false;
        return $this;
    }

    public function setPrepaidAmount(float $amount)
    {
        $this->data['prepaidAmount'] = number_format($amount, 2, '.', '');
        return $this;
    }

    public function setAmount(float $amount)
    {
        $this->data['amount'] = number_format($amount, 2, '.', '');
        return $this;
    }

    public function setAddressDelivery(string $address)
    {
        $this->data['addressDelivery'] = trim($address);
        return $this;
    }

    public function setPhoneRecipient($phone)
    {
        $this->data['phoneRecipient'] = $phone;
        return $this;
    }

    public function setItems(array $items)
    {
        foreach($items as $item) {
            $this->data['items'][] = $item->toArray();
        }
        return $this;
    }

    public function addItem(Item $item)
    {
        $this->data['items'][] = $item->toArray();
        return $this;
    }

    public function prepareOrderId(string $orderId): string
	{
		$orderId = str_replace(['/','#','?','|',' '], ['-'], $orderId);
		return $orderId;
	}

    public function toArray()
    {
        $items = $this->normalize($this->data['items']);
        $data = $this->data;
        $data['items'] = $items;
        return $data;
    }

    private function normalize($items)
	{
        $currentSum = 0;
        foreach($items as &$item) {
            $currentSum += $item['amount'] * 100 * $item['quantity'];
            $item['quantity'] = intval($item['quantity'] * 1000);
            $item['amount'] = intval($item['amount'] * 100);
        }
        $realAmount = intval($this->data['amount'] * 100);
		$currentSum = round($currentSum);
		if ($realAmount != 0 && $realAmount != $currentSum) {
			$coefficient = $realAmount / $currentSum;
			$realprice   = 0;
			$aloneId     = null;
			foreach ($items as $index => &$item) {
				$item['amount'] = round($coefficient * $item['amount']);
				$realprice += $item['amount'] * $item['quantity'] / 1000;
				if ($aloneId === null && $item['quantity'] === 1000) {
					$aloneId = $index;
				}

			}
			unset($item);
			if ($aloneId === null) {
				foreach ($items as $index => $item) {
					if ($aloneId === null && $item['quantity'] > 1000) {
						$aloneId = $index;
						break;
					}
				}
			}
			if ($aloneId === null) {
				$aloneId = 0;
			}

			$realprice = round($realprice);

			$diff = $realAmount - $realprice;
			if (abs($diff) >= 0.001) {
				if ($items[$aloneId]['quantity'] === 1000) {
					$items[$aloneId]['amount'] = round($items[$aloneId]['amount'] + $diff);
				} elseif (
					count($items) == 1
					&& abs(round($realAmount / $items[$aloneId]['quantity']) - $realAmount / $items[$aloneId]['quantity']) < 0.001
				) {
					$items[$aloneId]['amount'] = round($realAmount / $items[$aloneId]['quantity']);
				} elseif ($items[$aloneId]['quantity'] > 1000) {
					$tmpItem = $items[$aloneId];
					$item    = array(
						"quantity"       => 1000,
						"amount"          => round($tmpItem['amount'] + $diff),
						"name"           => $tmpItem['name'],
					);
					$items[$aloneId]['quantity'] -= 1000;
					array_splice($items, $aloneId + 1, 0, array($item));
				} else {
					$items[$aloneId]['amount'] = round($items[$aloneId]['amount'] + $diff / ($items[$aloneId]['quantity'] / 1000));

				}
			}
		}
        return $this->correctDimmensoin($items);
	}

	private function correctDimmensoin($items)
	{
		foreach ($items as &$item) {
			$item['quantity'] = number_format(round($item['quantity'] / 1000, 3), 3, '.', '');
			$item['amount']    = number_format(round($item['amount'] / 100, 2), 2, '.', '');
		}
        return $items;
	}
}
