<?php

namespace EveBlues\Model\Contact;

use EveBlues\Crest\Crest;
use EveBlues\Model\Alliance\AlliancesRepository;
use EveBlues\Model\ApiKey\ApiKey;
use EveBlues\Model\ApiKey\ApiKeysRepository;
use EveBlues\Model\Character\Character;
use EveBlues\Model\Character\CharactersFacade;
use EveBlues\Model\Character\CharactersRepository;
use EveBlues\Model\Corporation\CorporationsRepository;
use EveBlues\Model\User\User;
use EveBlues\XmlApi\XmlApi;
use Nette\Application\BadRequestException;
use Nette\Application\ForbiddenRequestException;

/**
 * @author Jakub Pistek <mail@jakubpistek.cz>
 */
class ContactsFacade {

	/** @var CharacterContactsRepository */
	private $characterContactsRepository;
	/** @var ContactLabelsRepository */
	private $labelsRepository;
	/** @var ApiKeysRepository */
	private $apiKeysRepository;
	/** @var CharactersRepository */
	private $charactersRepository;
	/** @var Crest */
	private $crest;
	/** @var CorporationContactsRepository */
	private $corporationContactsRepository;
	/** @var AllianceContactsRepository */
	private $allianceContactsRepository;
	/** @var CorporationsRepository */
	private $corporationsRepository;
	/** @var AlliancesRepository */
	private $alliancesRepository;
	/** @var XmlApi */
	private $xmlApi;
	/** @var CharactersFacade */
	private $charactersFacade;
	/** @var ContactsService */
	private $contactsService;

	public function __construct(
		ApiKeysRepository $apiKeysRepository,
		AlliancesRepository	$alliancesRepository,
		Crest $crest,
		CorporationsRepository $corporationsRepository,
		CharactersRepository $charactersRepository,
		CharactersFacade $charactersFacade,
		CharacterContactsRepository $characterContactsRepository,
		CorporationContactsRepository $corporationContactsRepository,
		AllianceContactsRepository $allianceContactsRepository,
		ContactLabelsRepository $labelsRepository,
		ContactsService $contactsService,
		XmlApi $xmlApi
	) {
		$this->characterContactsRepository = $characterContactsRepository;
		$this->labelsRepository = $labelsRepository;
		$this->apiKeysRepository = $apiKeysRepository;
		$this->charactersRepository = $charactersRepository;
		$this->crest = $crest;
		$this->corporationContactsRepository = $corporationContactsRepository;
		$this->allianceContactsRepository = $allianceContactsRepository;
		$this->corporationsRepository = $corporationsRepository;
		$this->alliancesRepository = $alliancesRepository;
		$this->xmlApi = $xmlApi;
		$this->charactersFacade = $charactersFacade;
		$this->contactsService = $contactsService;
	}

	public function getContacts(User $owner, ApiKey $apiKey, int $characterId) :Character {

		/** @var Character $character */
		$character = $this->charactersRepository->getById($characterId);
		if (!$character) {
			throw new BadRequestException();
		}
		if ($owner !== $apiKey->owner) {
			throw new ForbiddenRequestException();
		}

		$contactData = $this->xmlApi->getContactList($apiKey, $character->id);

		$character->isDownloaded = true;
		$this->charactersRepository->persistAndFlush($character);

		$labels = $this->labelsRepository->createNew($character, $contactData['contactLabels']);
		$contacts = $this->characterContactsRepository->createNew($character, $labels, $contactData['contactList']);
		$this->createCharacterContacts($contacts);

		// nechci kontakty pokud je corpa NPC
		if (!$character->corporation->isNpc) {
			$contacts = $this->corporationContactsRepository->createNew($character->corporation, $contactData['corporateContactList']);
			$this->createCharacterContacts($contacts);
		}

		if ($character->corporation->alliance) {
			$contacts = $this->allianceContactsRepository->createNew($character->corporation->alliance, $contactData['allianceContactList']);
			$this->createCharacterContacts($contacts);
		}

		return $character;
	}

	public function copyContacts(Character $from, Character $to) {

		$filteredContacts = $this->contactsService->filterContacts(
			$from->contacts,
			$from->corporation->contacts,
			$from->corporation->alliance->contacts
		);

//		foreach ($from->contacts as $contact) {
//			if ($contact->type === Contact::TYPE_CHARACTER) {
//				$this->crest->addContact($to, $contact);
//				break;
//			}
//		}

	}

	/**
	 * @param CharacterContact[]|CorporationContact[]|AllianceContact[] $contacts
	 */
	private function createCharacterContacts($contacts) {

		foreach ($contacts as $contact) {

			switch ($contact->type) {
				case Contact::TYPE_CHARACTER:
					if (!$this->charactersRepository->getById($contact->subjectId)) {
						$this->charactersRepository->createNewStub($contact->subjectId, $contact->subjectName);
					}
					break;
				case Contact::TYPE_CORPORATION:
					if (!$this->corporationsRepository->getById($contact->subjectId)) {
						$this->corporationsRepository->createNewStub($contact->subjectId, $contact->subjectName);
					}
					break;
				case Contact::TYPE_ALLIANCE:
					if (!$this->alliancesRepository->getById($contact->subjectId)) {
						$this->alliancesRepository->createNewStub($contact->subjectId, $contact->subjectName);
					}
			}

		}
	}
}