<?php
error_reporting(-1);
mb_internal_encoding('utf-8');
header("Content-Type: text/plain; charset=utf-8");

class Organisation {
	private $name;
	private $departments = array();

	public function __construct($name) {
		$this->name = $name;
	}

	public function getOrganisationName() {
		return $this->name;
	}

	public function getDepartments() {
		return $this->departments;
	}

	public function addDepartment(Department $department) {
		$this->departments[] = $department;
	}

	public function makeReport() { //хз куда если не сюда сложить подобный метод
		foreach ($this->departments as $dep) {
			echo $dep->getDepName() . "   " . $dep->getTotalDepWorkers() . "   " . $dep->getTotalDepStuff('Salary') . "   ";
			echo $dep->getTotalDepStuff('Coffe') . "   " . $dep->getTotalDepStuff('Papers') . "   " . $dep->getTotalDepEffectiveness();
			echo "\n";
		}
	}
}

class Department {
	private $name;
	private $workers = array();

	public function __construct($name) {
		$this->name = $name;
	}

	public function getDepName() {
		return $this->name;
	}

	public function addWorker(Worker $worker) {
		$this->workers[] = $worker;
	}

	public function addWorkers(array $workers) {
		foreach ($workers as $worker) {
			if (is_subclass_of($worker, 'Worker')) {
				$this->addWorker($worker);
			}
		}
	}

	public function getWorkers() {
		return $this->workers;
	}

	public function getTotalDepWorkers() {
		return count($this->workers);
	}

	public function getTotalDepStuff ($something) { //Salary, Coffe, Papers    В процессе написания оказались 3 одинаковых функции, объединил их
		$result = 0;
		$something = 'getWorker' . mb_convert_case($something, MB_CASE_TITLE);
		foreach ($this->workers as $worker) {
			$result += $worker->$something();
		}
		return $result;
	}

	public function getTotalDepEffectiveness() {
		if ($this->getTotalDepStuff('Papers') == 0) { //если есть пустой департамент, то ловим деление на 0, как почитаю про исключения, то заменю
			return "N/A";
		}
		return round($this->getTotalDepStuff('Salary') / $this->getTotalDepStuff('Papers'), 2);
	}

}

abstract class Worker {
	//private $salary;  //и без них всё работает, но если их разкоментить, то будут в наследниках мусорные пустые поля от родителя
	//private $coffe;
	//private $papers;
	private $rang;
	private $leader;

	public function __construct($rang = 1, $leader = false) {
		$this->rang = $rang;
		$this->leader = $leader;
	}

	public function getWorkerSalary() {
		if ($this->rang == 3) {
			$result = $this->salary * 1.5;
		} elseif ($this->rang == 2) {
			$result = $this->salary * 1.25;
		} else {
			$result = $this->salary;
		}
		if ($this->leader == true) {
			$result *= 1.5;
		}
		return $result;
	}

	public function getWorkerCoffe() {
		if ($this->leader == true) {
			return $this->coffe * 2;
		} else {
			return $this->coffe;
		}
	}

	public function getWorkerPapers() {
		if ($this->leader == true) {
			return 0;
		} else {
			return $this->papers;
		}
	}
}
class Manager extends Worker{
	protected $salary = 500; //private нельзя, тогда у родителя нет доступа к свойствам.
	protected $coffe = 20;
	protected $papers = 200;
}

class Marketer extends Worker {
	protected $salary = 400;
	protected $coffe = 15;
	protected $papers = 150;
}

class Engineer extends Worker {
	protected $salary = 200;
	protected $coffe = 5;
	protected $papers = 50;
}

class Analyst extends Worker {
	protected $salary = 800;
	protected $coffe = 50;
	protected $papers = 5;
}

class WorkersFactory {
	static public function createWorkers($class, $amount, $rang, $leader){
		$workers = [];
		for ($i = 0; $i < $amount; $i++) {
			$workers[] = new $class($rang, $leader);
		}
		return $workers;
	}

}

$vector = new Organisation('Вектор');

$buyDep = new Department('Закупок');
$vector->addDepartment($buyDep);
$buyDep->addWorkers(WorkersFactory::createWorkers('Manager', 9, 1, false));
$buyDep->addWorkers(WorkersFactory::createWorkers('Manager', 3, 2, false));
$buyDep->addWorkers(WorkersFactory::createWorkers('Manager', 2, 3, false));
$buyDep->addWorkers(WorkersFactory::createWorkers('Marketer', 2, 1, false));
$buyDep->addWorkers(WorkersFactory::createWorkers('Manager', 1, 2, true));

$saleDep = new Department('Продаж');
$vector->addDepartment($saleDep);
$saleDep->addWorkers(WorkersFactory::createWorkers('Manager', 12, 1, false));
$saleDep->addWorkers(WorkersFactory::createWorkers('Marketer', 6, 1, false));
$saleDep->addWorkers(WorkersFactory::createWorkers('Analyst', 3, 1, false));
$saleDep->addWorkers(WorkersFactory::createWorkers('Analyst', 2, 2, false));
$saleDep->addWorkers(WorkersFactory::createWorkers('Marketer', 1, 2, true));

$advDep = new Department('Рекламы');
$vector->addDepartment($advDep);
$advDep->addWorkers(WorkersFactory::createWorkers('Marketer', 15, 1, false));
$advDep->addWorkers(WorkersFactory::createWorkers('Marketer', 10, 2, false));
$advDep->addWorkers(WorkersFactory::createWorkers('Manager', 8, 1, false));
$advDep->addWorkers(WorkersFactory::createWorkers('Engineer', 2, 1, false));
$advDep->addWorkers(WorkersFactory::createWorkers('Marketer', 1, 3, true));

$logDep = new Department('Логистики');
$vector->addDepartment($logDep);
$logDep->addWorkers(WorkersFactory::createWorkers('Manager', 13, 1, false));
$logDep->addWorkers(WorkersFactory::createWorkers('Manager', 5, 2, false));
$logDep->addWorkers(WorkersFactory::createWorkers('Engineer', 5, 1, false));
$logDep->addWorkers(WorkersFactory::createWorkers('Manager', 1, 1, true));

$vector->makeReport();

//var_dump($vector);

//var_dump($dep1);