<?php

declare(strict_types=1);
namespace Tests\Adawolfa\Fucktura;
use Adawolfa\Fucktura\Entity\BankAccount;
use Adawolfa\Fucktura\Entity\Invoice;
use Adawolfa\Fucktura\Entity\Party;
use Adawolfa\Fucktura\I18n\Country;
use Adawolfa\Fucktura\I18n\Currency;
use Adawolfa\Fucktura\I18n\Locale;
use Doctrine\ORM\EntityManager;
use DateTimeImmutable;

final class EntityFactory
{

	public function __construct(private EntityManager $em)
	{
	}

	public function createParty(Party\Info $info = null, Party\Address $address = null): Party
	{
		$party = new Party($info ?? $this->createInfo(), $address ?? $this->createAddress());
		$this->em->persist($party);
		$this->em->flush();
		return $party;
	}

	public function createInvoice(Party $vendor = null, Party $customer = null): Invoice
	{
		$invoice = new Invoice(
			'123456',
			'E2587F23-8BBD-4D96-906A-BE5A14D063AB',
			$vendor ?? $this->createParty(),
			$customer ?? $this->createParty(),
			DateTimeImmutable::createFromFormat('Y-m-d', '2022-01-01'),
			DateTimeImmutable::createFromFormat('Y-m-d', '2022-01-15'),
			Locale::cs_CZ,
			Currency::CZK,
			$this->createBankAccount(),
		);

		$this->em->persist($invoice);
		$this->em->flush();

		return $invoice;
	}

	public function createBankAccount(): BankAccount
	{
		$bankAccount = new BankAccount(
			'12345678',
			'1337',
			'Bank',
		);

		$bankAccount->iban = '0000000000000000000000000000000000';
		$bankAccount->bic  = '12345678';

		$this->em->persist($bankAccount);
		$this->em->flush();

		return $bankAccount;
	}

	public function createInvoiceLine(
		Invoice $invoice,
		string  $description,
		string  $unitPrice,
		string  $quantity,
	): Invoice\Line
	{
		$line = new Invoice\Line($invoice, $description, $unitPrice, $quantity);

		$this->em->persist($line);
		$this->em->flush();
		$this->em->refresh($invoice);

		return $line;
	}

	public function createInfo(string $name = 'Party', ?string $cin = '12345678', string $tin = null): Party\Info
	{
		return new Party\Info($name, $cin, $tin);
	}

	public function createAddress(
		string  $street         = 'Street',
		string  $buildingNumber = '123',
		string  $city           = 'City',
		string  $zip            = '00 000',
		Country $country        = Country::CZ,
	): Party\Address
	{
		return new Party\Address($street, $buildingNumber, $city, $zip, $country);
	}

}