<?php

class Company {
 
    public $departments = [];
    
    public function addDepartment($department) 
    {
        
        array_push($this->departments, $department);
        
    }

    public function countTotalEmployees()
    {
 
        $totalEmployees = 0;
        foreach ($this->departments as $department){
                $totalEmployees += $department->countEmployees($department->employees);
        }
        return $totalEmployees;
 
    }
 
    public function countTotalCoffeConsumption()
    {
 
        $totalCoffeConsumption = 0;
        foreach ($this->departments as $department) {
            $totalCoffeConsumption += $department->countCoffeConusmption($department->employees);
        }
        return $totalCoffeConsumption;
 
    }
 
    public function countTotalSalary()
    {
 
        $totalSalary = 0;
        foreach ($this->departments as $department) {
            $totalSalary += $department->countSalary($department->employees);
        }
        return $totalSalary;
 
    }
 
    public function countTotalReports()
    {
 
        $totalReports = 0;
        foreach ($this->departments as $department) {
            $totalReports += $department->countReports($department->employees);
        }
        return $totalReports;
 
    }
 
    public function countTotalMainReports()
    {
 
        $totalMainReports = 0;
        foreach ($this->departments as $department) {
            $totalMainReports += $department->countMainReports($department->employees);
        }
        return $totalMainReports;
 
    }
 
    public function countTotalBlueprints()
    {
 
        $totalBlueprints = 0;
        foreach ($this->departments as $department) {
            $totalBlueprints += $department->countBlueprints($department->employees);
        }
        return $totalBlueprints;
 
    }

}
 
class Department
{
 
    public $employees = [];
    public $name; 
    
    public function createEmployee($rank, $isBoss, $proffession) 
    {
    
        if($proffession == "Manager" ){
            array_push($this->employees, new Manager($rank, $isBoss, $proffession));
        } elseif ($proffession == "Marketolog") {
            array_push($this->employees, new Marketolog($rank, $isBoss, $proffession));
        } elseif ($proffession == "Engeneer") {
            array_push($this->employees, new Engeneer($rank, $isBoss, $proffession));
        } elseif ($proffession == "Analyst") {
            array_push($this->employees, new Analyst($rank, $isBoss, $proffession));
        }
    
    }
    
    public function  deleteEmployee($rank, $isBoss, $proffession)
    {
        
        foreach ($this->employees as $key => $employee){
            if($rank == $employee->rank && $isBoss == $employee->isBoss && $proffession == $employee->proffession) {
                unset($this->employees[$key]);
                break;
            }
        }
    }


    public function  countEmployees()
    {
 
        return count($this->employees);
 
    }
 
    public function countCoffeConusmption ()
    {
 
        $dpCoffeConsumption = 0;
        foreach ($this->employees as $employee){
            $dpCoffeConsumption += $employee->countEmployeeCoffeConusmption ();
        }
        return $dpCoffeConsumption;
 
    }
 
    public function countSalary ()
    {
 
        $dpSalary = 0;
        foreach ($this->employees as $employee) {
            $dpSalary += $employee->countEmployeeSalary();
            }
        return $dpSalary;
    }
 
    public function  countReports ()
    {
 
        $dpReports = 0;
        foreach ($this->employees as $employee) {
            $dpReports += $employee->getReports();
        }
        return $dpReports;
    }
 
    public function  countBlueprints ()
    {
 
        $dpBlueprints = 0;
        foreach ($this->employees as $employee) {
            $dpBlueprints += $employee->getBlueprints();
        }
        return $dpBlueprints;
    }
 
    public function  countMainReports ()
    {
 
        $dpMainReports = 0;
        foreach ($this->employees as $employee) {
            $dpMainReports += $employee->getMainReports();
        }
        return $dpMainReports;
    }

}
 
abstract class Employee
{
     function __construct ($rank, $isBoss, $proffession)
    {
        $this->isBoss = $isBoss;
        $this->rank = $rank;
        $this->proffession = $proffession;
 
    }
    
    
    abstract function getProfession();
    protected abstract function getAmountOfCoffe();
    protected abstract function getBaseSalary();
    abstract function getReports();
    abstract function getMainReports();
    abstract function getBlueprints();

    
    public function countEmployeeCoffeConusmption ()
    {
 
        $employeeCoffeConsumption = 0;
            if ($this->isBoss == true) {
                $employeeCoffeConsumption = $this->getAmountOfCoffe() * 2;
            } else {
                $employeeCoffeConsumption = $this->getAmountOfCoffe(); 
            } 
        return $employeeCoffeConsumption;
 
    }
 
    public function countEmployeeSalary ()
    {
 
        $dpSalary = 0;
            if ($this->rank == 3) {
                $dpSalary += $this->getBaseSalary() + ($this->getBaseSalary() * 0.5);
            } elseif ($this->rank == 2) {
                $dpSalary += $this->getBaseSalary() + ($this->getBaseSalary() * 0.25);
            } else {
                $dpSalary += $this->getBaseSalary();
            }
        return $dpSalary;
        
    }
 
    
 
}
 
class Manager extends Employee
{
    
    function getProfession()
    {
    
        return $proffession = "Manager";
         
    }
    
    protected function getBaseSalary()
    {
        
        return $baseSalary = 500;
        
    }
    protected function getAmountOfCoffe()
    {
        
        return $amountOfCoffe = 25;
        
    }
    
    function getReports()
    {
        
        return $reports = 200;
        
    }
    
    function getMainReports()
    {
        
        return $mainReports = 0;
        
    }
    
    function getBlueprints()
    {
        
        return $blueprints = 0;
        
    }
 
}
 
class Engeneer extends Employee
{
    
    function getProfession()
    {
    
        return $proffession = "Engeneer";
         
    }
    
    protected function getBaseSalary()
    {
        
        return $baseSalary = 200;
        
    }
    protected function getAmountOfCoffe()
    {
        
        return $amountOfCoffe = 5;
        
    }
    
    function getReports()
    {
        
        return $reports = 0;
        
    }
    
    function getMainReports()
    {
        
        return $mainReports = 0;
        
    }
    
    function getBlueprints()
    {
        
        return $blueprints = 50;
        
    }
 
}
 
class Marketolog extends Employee
{
    
    function getProfession()
    {
    
        return $proffession = "Marketolog";
         
    }
    
    protected function getBaseSalary()
    {
        
        return $baseSalary = 400;
        
    }
    protected function getAmountOfCoffe()
    {
        
        return $amountOfCoffe = 15;
        
    }
    
    function getReports()
    {
        
        return $reports = 150;
        
    }
    
    function getMainReports()
    {
        
        return $mainReports = 0;
        
    }
    
    function getBlueprints()
    {
        
        return $blueprints = 0;
        
    }
 
}
 
class Analyst extends Employee
{
    
    function getProfession()
    {
    
        return $proffession = "Analyst";
         
    }
    
    protected function getBaseSalary()
    {
        
        return $baseSalary = 800;
      //  return $baseSalary = 1100; // Значение для второй антикризисной меры
        
        
    }
    protected function getAmountOfCoffe()
    {
        
        return $amountOfCoffe = 50;
       // return $amountOfCoffe = 75; // Значение для второй антикризисной меры
    }
    
    function getReports()
    {
        
        return $reports = 0;
        
    }
    
    function getMainReports()
    {
        
        return $mainReports = 5;
        
    }
    
    function getBlueprints()
    {
        
        return $blueprints = 0;
        
    }
 
}

class Antycrysis1 
{
    
    private function countEngeneers($department) : int
    {
       $numberOfEngneers = 0; 
       foreach($department->employees as $employee) {
           if ($employee->proffession == "Engeneer") {
               $numberOfEngneers++;
           }
       } 
        return $numberOfEngneers;
    }
    
    public function  fireEngeneers($department) 
    {
        
        for($i = 0; $i < round($this->countEngeneers($department) * 0.4, PHP_ROUND_HALF_UP); $i++) {
            $department->deleteEmployee(1, 0, "Engeneer");
        }
    }
    
}

class Antycrisys2
{
    
    public function replaseBoss($department) 
    {
        
        foreach ($department->employees as $employee){
            if ($employee->isBoss == 1 && $employee->proffession != "Analyst" ){
                $employee->isBoss = 0;
            }
        }    
        foreach ($department->employees as $employee){   
            if ($employee->isBoss == 0 && $employee->proffession == "Analyst" && $employee->rank == 3) {
                $employee->isBoss = 1;
                break;     
            }
        }
        foreach ($department->employees as $employee){   
            if ($employee->isBoss == 0 && $employee->proffession == "Analyst" && $employee->rank == 2) {
                $employee->isBoss = 1;
                break;     
            }
        }
        foreach ($department->employees as $employee){   
            if ($employee->isBoss == 0 && $employee->proffession == "Analyst" && $employee->rank == 1) {
                $employee->isBoss = 1;
                break;     
            }
        }
               
    }
    
}

class Antycrisys3
{
    
    public function promoteManagers($department)
    {
         
        for($i = 0; $i < round($this->countManagers2($department) * 0.5); $i++) {
            $this->riseManagers2($department);
        }
        for($i = 0; $i < round($this->countManagers1($department) * 0.5); $i++) {
            $this->riseManagers1($department);
        }
        
    }
    
    private function countManagers1($department) : int
    {
        
       $numberOfManagers1 = 0;
       
       foreach($department->employees as $employee) {
           if ($employee->proffession == "Manager" && $employee->rank == 1 ) {
               
               $numberOfManagers1++;
           }
       } 
       return $numberOfManagers1;
       
    }
    private function countManagers2($department)  : int
    {   
        
        $numberOfManagers2 = 0;
        foreach($department->employees as $employee) {
           if ($employee->proffession == "Manager" && $employee->rank == 2 ) {
               $numberOfManagers2++;
           }
       } 
       return $numberOfManagers2; 
       
    }

    private function riseManagers1($department)
    {
        foreach ($department->employees as $employee){
            if ($employee->proffession == "Manager" && $employee->rank == 1){
                $employee->rank = 2;
                break;
            }
        }
        
    }
    private function riseManagers2($department)
    {
        foreach ($department->employees as $employee){
            if ($employee->proffession == "Manager" && $employee->rank == 2){
                $employee->rank = 3;
                break;
            }
        }
        
    }
}


$purchaseDepartment = new Department();
$purchaseDepartment->name = "Purchase Department";
$purchaseDepartment->createEmployee(2, 1, "Manager");
for($i = 0; $i < 9; $i++){
    $purchaseDepartment->createEmployee(1, 0, "Manager");
}
for($i = 0; $i < 3; $i++){
    $purchaseDepartment->createEmployee(2, 0, "Manager");
}
for($i = 0; $i < 2; $i++){
    $purchaseDepartment->createEmployee(3, 0, "Manager");
}
for($i = 0; $i < 2; $i++){
    $purchaseDepartment->createEmployee(1, 0, "Marketolog");
}

$sellersDepartment = new Department();
$sellersDepartment->name = "Sellers Department";
$sellersDepartment->createEmployee(2, 1, "Marketolog");
for($i = 0; $i < 12; $i++){
    $sellersDepartment->createEmployee(1, 0, "Manager");
}
for($i = 0; $i < 6; $i++){
    $sellersDepartment->createEmployee(1, 0, "Marketolog");
}
for($i = 0; $i < 3; $i++){
    $sellersDepartment->createEmployee(1, 0, "Analyst");
}
for($i = 0; $i < 2; $i++){
    $sellersDepartment->createEmployee(2, 0, "Analyst");
}
for($i = 0; $i < 2; $i++){
    $sellersDepartment->createEmployee(3, 0, "Analyst");
}

$marketingDepartment = new Department();
$marketingDepartment->name = "Marketing Department";
$marketingDepartment->createEmployee(3, 1, "Marketolog");
for($i = 0; $i < 15; $i++){
    $marketingDepartment->createEmployee(1, 0, "Marketolog");
}
for($i = 0; $i < 10; $i++){
    $marketingDepartment->createEmployee(2, 0, "Marketolog");
}
for($i = 0; $i < 8; $i++){
    $marketingDepartment->createEmployee(1, 0, "Manager");
}
for($i = 0; $i < 2; $i++){
    $marketingDepartment->createEmployee(1, 0, "Engeneer");
}

$logisticDepartment = new Department();
$logisticDepartment->name = "Logistic Department";
$logisticDepartment->createEmployee(1, 1, "Manager");
for($i = 0; $i < 13; $i++){
    $logisticDepartment->createEmployee(1, 0, "Manager");
}
for($i = 0; $i < 5; $i++){
    $logisticDepartment->createEmployee(2, 0, "Manager");
}
for($i = 0; $i < 5; $i++){
    $logisticDepartment->createEmployee(1, 0, "Engeneer");
}

$company = new Company;
$company->addDepartment($purchaseDepartment);
$company->addDepartment($sellersDepartment);
$company->addDepartment($marketingDepartment);
$company->addDepartment($logisticDepartment);

/*$antycrysis1 = new Antycrysis1();
$antycrysis1->fireEngeneers($marketingDepartment);  // Для первой антикризиной меры
*/

/*$antycrysis2 = new Antycrisys2();
$antycrysis2->replaseBoss($sellersDepartment);  // Для второй антикризиной меры
*/

/*$antycrysis3 = new Antycrisys3();
$antycrysis3->promoteManagers($purchaseDepartment);  // Для третьей антикризиной меры
*/

foreach ($company->departments as $department){
echo  $department->name . "\n" .
     "Employees: " . $department->countEmployees() . "\n" .   
     "Coffe: " . $department->countCoffeConusmption() . "\n" .
     "Salary: " . $department->countSalary() . "\n" .
     "Reports: " . $department->countReports() . "\n" .
     "MainReports: " . $department->countMainReports() . "\n" .
     "Blueprints: " . $department->countBlueprints() . "\n" ;
 
echo str_repeat("__", 30) . "\n";
}
 
echo "Total Employees: " . $company->countTotalEmployees() . "\n" . 
     "Total coffe: " . $company->countTotalCoffeConsumption() . "\n" .
     "Total salary: " . $company->countTotalSalary() . "\n" .
     "Total reports: " . $company->countTotalReports() . "\n" .
     "Total main reports: " . $company->countTotalMainReports() . "\n" .
     "Total blueprints: " . $company->countTotalBlueprints() . "\n";
 
echo str_repeat("__", 30) . "\n";
 
echo "Avarage Employees: " . round($company->countTotalEmployees() / count($company->departments), 2) . "\n" . 
     "Avarage coffe: " . round($company->countTotalCoffeConsumption() / count($company->departments), 2) . "\n" .
     "Avarage salary: " . round($company->countTotalSalary() / count($company->departments), 2) . "\n" .
     "Avarage reports: " . round($company->countTotalReports() / count($company->departments), 2) . "\n" .
     "Avarage main reports: " . round($company->countTotalMainReports() / count($company->departments), 2) ."\n" .
     "Avarage blueprints: " . round($company->countTotalBlueprints() / count($company->departments), 2) . "\n";