<?php
error_reporting(-1);
mb_internal_encoding('utf-8');

class Managment
{
    public $salary = 500;
    public $coffee = 20;
    public $pages = 200;
    public $rang;
    public $bodycount;
    public $isBoss = FALSE;

    public function __construct($rang, $bodycount)
    {
        $this->rang = $rang;
        $this->bodycount = $bodycount;
    }

    public function getStatistic()
    {
        $ko1 = 0;           // коэффициент для умножения результатов по рангам
        switch($this->rang):
            case 1:
                $ko1 = 1;
                break;
            case 2:
                $ko1 = 1.25;
                break;
            case 3:
                $ko1 = 1.5;
                break;
        endswitch;

        $ko2 = 0;           //коэффициент для босса
        switch($this->isBoss):
            case FALSE:
                $ko2 = 1;
                break;
            case TRUE:
                $ko2 = 2;
                break;
        endswitch;

        //считаю статистику по сотрудникам
        $statistic = [
            "salary"=> $this->salary*$this->bodycount*$ko1*$ko2,
            "coffee"=> $this->coffee*$this->bodycount*$ko2,
            "pages"=> $this->pages*$this->bodycount,
            ];
        //проверяю, босс ли, чтобы стереть его страницы
        if($this->isBoss){
            $statistic["pages"] = 0;
        }
        return $statistic;
    }

}

class Marketing
{
    public $salary = 400;
    public $coffee = 15;
    public $pages = 150;
    public $rang;
    public $bodycount;
    public $isBoss = FALSE;

    public function __construct($rang, $bodycount)
    {
        $this->rang = $rang;
        $this->bodycount = $bodycount;
    }

    public function getStatistic()
    {
        $ko1 = 0;
        switch($this->rang):
            case 1:
                $ko1 = 1;
                break;
            case 2:
                $ko1 = 1.25;
                break;
            case 3:
                $ko1 = 1.5;
                break;
        endswitch;

        $ko2 = 0;
        switch($this->isBoss):
            case FALSE:
                $ko2 = 1;
                break;
            case TRUE:
                $ko2 = 2;
                break;
        endswitch;


        $statistic = [
            "salary"=> $this->salary*$this->bodycount*$ko1*$ko2,
            "coffee"=> $this->coffee*$this->bodycount*$ko2,
            "pages"=> $this->pages*$this->bodycount,
        ];

        if($this->isBoss){
            $statistic["pages"] = 0;
        }
        return $statistic;
    }
}

class Engineer
{
    public $salary = 200;
    public $coffee = 5;
    public $pages = 50;
    public $rang;
    public $bodycount;
    public $isBoss = FALSE;

    public function __construct($rang, $bodycount)
    {
        $this->rang = $rang;
        $this->bodycount = $bodycount;
    }

    public function getStatistic()
    {
        $ko1 = 0;
        switch($this->rang):
            case 1:
                $ko1 = 1;
                break;
            case 2:
                $ko1 = 1.25;
                break;
            case 3:
                $ko1 = 1.5;
                break;
        endswitch;

        $ko2 = 0;
        switch($this->isBoss):
            case FALSE:
                $ko2 = 1;
                break;
            case TRUE:
                $ko2 = 2;
                break;
        endswitch;


        $statistic = [
            "salary"=> $this->salary*$this->bodycount*$ko1*$ko2,
            "coffee"=> $this->coffee*$this->bodycount*$ko2,
            "pages"=> $this->pages*$this->bodycount,
        ];

        if($this->isBoss){
            $statistic["pages"] = 0;
        }
        return $statistic;
    }
}

class Analysis
{
    public $salary = 800;
    public $coffee = 50;
    public $pages = 5;
    public $rang;
    public $bodycount;
    public $isBoss = FALSE;

    public function __construct($rang, $bodycount)
    {
        $this->rang = $rang;
        $this->bodycount = $bodycount;
    }

    public function getStatistic()
    {
        $ko1 = 0;
        switch($this->rang):
            case 1:
                $ko1 = 1;
                break;
            case 2:
                $ko1 = 1.25;
                break;
            case 3:
                $ko1 = 1.5;
                break;
        endswitch;

        $ko2 = 0;
        switch($this->isBoss):
            case FALSE:
                $ko2 = 1;
                break;
            case TRUE:
                $ko2 = 2;
                break;
        endswitch;


        $statistic = [
            "salary"=> $this->salary*$this->bodycount*$ko1*$ko2,
            "coffee"=> $this->coffee*$this->bodycount*$ko2,
            "pages"=> $this->pages*$this->bodycount,
        ];

        if($this->isBoss){
            $statistic["pages"] = 0;
        }
        return $statistic;
    }
}

function getStatsOfBuying()   //функция получения полной статистики по отделу покупок
{
    //список сотрудников, единственное, что нужно менять, если сокращаем, увеличиваем кол-во сотрудников
    $staff = [];
    $men = new Managment(1, 9);
    $staff[] = $men;
    $men = new Managment(2, 3);
    $staff[] = $men;
    $men = new Managment(3, 2);
    $staff[] = $men;
    $men = new Marketing(1, 2);
    $staff[] = $men;
    $men = new Managment(2, 1);
    $men->isBoss = TRUE;
    $staff[] = $men;
    //конец списка сотрудников

    $totalSalary = $totalCoffee = $totalPages = $totalBodies = 0;
    foreach($staff as $man){
        $totalBodies += $man->bodycount;
        $totalSalary += $man->getStatistic()["salary"];
        $totalCoffee += $man->getStatistic()["coffee"];
        $totalPages += $man->getStatistic()["pages"];
    }
    $resultStats =
        [
            "bodies" => $totalBodies,
            "salary" => $totalSalary,
            "coffee" => $totalCoffee,
            "pages" => $totalPages,
        ];
    return $resultStats; //возвращаю массив со всей информацией
}

function getStatsOfSelling()
{
    $staff = [];
    $men = new Managment(1, 12);
    $staff[] = $men;
    $men = new Marketing(1, 6);
    $staff[] = $men;
    $men = new Analysis(1, 3);
    $staff[] = $men;
    $men = new Analysis(2, 2);
    $staff[] = $men;
    $men = new Marketing(2, 1);
    $men->isBoss = TRUE;
    $staff[] = $men;

    $totalSalary = $totalCoffee = $totalPages = $totalBodies = 0;
    foreach($staff as $man){
        $totalBodies += $man->bodycount;
        $totalSalary += $man->getStatistic()["salary"];
        $totalCoffee += $man->getStatistic()["coffee"];
        $totalPages += $man->getStatistic()["pages"];
    }
    $resultStats =
        [
            "bodies" => $totalBodies,
            "salary" => $totalSalary,
            "coffee" => $totalCoffee,
            "pages" => $totalPages,
        ];
    return $resultStats;
}

function getStatsOfAds()
{
    $staff = [];
    $men = new Marketing(1, 15);
    $staff[] = $men;
    $men = new Marketing(1, 6);
    $staff[] = $men;
    $men = new Analysis(1, 3);
    $staff[] = $men;
    $men = new Analysis(2, 2);
    $staff[] = $men;
    $men = new Marketing(3, 1);
    $men->isBoss = TRUE;
    $staff[] = $men;

    $totalSalary = $totalCoffee = $totalPages = $totalBodies = 0;
    foreach($staff as $man){
        $totalBodies += $man->bodycount;
        $totalSalary += $man->getStatistic()["salary"];
        $totalCoffee += $man->getStatistic()["coffee"];
        $totalPages += $man->getStatistic()["pages"];
    }
    $resultStats =
        [
            "bodies" => $totalBodies,
            "salary" => $totalSalary,
            "coffee" => $totalCoffee,
            "pages" => $totalPages,
        ];
    return $resultStats;
}

function getStatsOfLogistics()
{
    $staff = [];
    $men = new Managment(1, 13);
    $staff[] = $men;
    $men = new Managment(2, 5);
    $staff[] = $men;
    $men = new Engineer(1, 5);
    $staff[] = $men;
    $men = new Managment(1, 1);
    $men->isBoss = TRUE;
    $staff[] = $men;

    $totalSalary = $totalCoffee = $totalPages = $totalBodies = 0;
    foreach($staff as $man){
        $totalBodies += $man->bodycount;
        $totalSalary += $man->getStatistic()["salary"];
        $totalCoffee += $man->getStatistic()["coffee"];
        $totalPages += $man->getStatistic()["pages"];
    }
    $resultStats =
        [
            "bodies" => $totalBodies,
            "salary" => $totalSalary,
            "coffee" => $totalCoffee,
            "pages" => $totalPages,
        ];
    return $resultStats;
}

//функция аналог str_pad, только для кириллицы
function mb_str_pad($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT, $encoding = NULL)
{
    $encoding = $encoding === NULL ? mb_internal_encoding() : $encoding;
    $padBefore = $dir === STR_PAD_BOTH || $dir === STR_PAD_LEFT;
    $padAfter = $dir === STR_PAD_BOTH || $dir === STR_PAD_RIGHT;
    $pad_len -= mb_strlen($str, $encoding);
    $targetLen = $padBefore && $padAfter ? $pad_len / 2 : $pad_len;
    $strToRepeatLen = mb_strlen($pad_str, $encoding);
    $repeatTimes = ceil($targetLen / $strToRepeatLen);
    $repeatedString = str_repeat($pad_str, max(0, $repeatTimes));
    $before = $padBefore ? mb_substr($repeatedString, 0, floor($targetLen), $encoding) : '';
    $after = $padAfter ? mb_substr($repeatedString, 0, ceil($targetLen), $encoding) : '';
    return $before . $str . $after;
}

//пишу функцию для вставки пробелов справа
function padRight($string, $length)
{
    $spaces = $length - mb_strlen($string);
    if($spaces>0)
    {
        $string=mb_str_pad($string, mb_strlen($string) + $spaces, " ", STR_PAD_RIGHT);
    }
    return $string;
}

//пишу функцию для вставки пробелов слева
function padLeft($string, $length)
{
    $spaces = $length - mb_strlen($string);
    if($spaces>0)
    {
        $string=mb_str_pad($string, mb_strlen($string) + $spaces, " ", STR_PAD_LEFT);
    }
    return $string;
}

//два типа колонок
$col1 = 25;
$col2 = 15;

//верхняя строка таблицы
echo padRight("Департамент", $col1) .
    padLeft("сотр.", $col2) .
    padLeft("тугр.", $col2) .
    padLeft("кофе", $col2) .
    padLeft("стр.", $col2) .
    padLeft("тугр./стр.", $col2) .
    "\n";

echo str_repeat("-", 100)."\n";

$totalBodies = $totalSalary = $totalCoffee = $totalPages = $totalBalance = 0;

//делаю массив массивов статистики по всем департаментам
$statistics = [
    "Закупок" => getStatsOfBuying(),
    "Продаж" => getStatsOfSelling(),
    "Рекламы" => getStatsOfAds(),
    "Логистики" => getStatsOfLogistics(),
];

//прохожусь по массиву массивов
foreach($statistics as $department => $datum){
    $balance = round($datum["salary"] / $datum["pages"], 2);
    echo padRight("$department", $col1).
        padLeft($datum["bodies"], $col2) .
        padLeft($datum["salary"], $col2) .
        padLeft($datum["coffee"], $col2) .
        padLeft($datum["pages"], $col2) .
        padLeft($balance, $col2) .
        "\n";
    $totalBodies += $datum["bodies"];
    $totalSalary += $datum["salary"];
    $totalCoffee += $datum["coffee"];
    $totalPages += $datum["pages"];
    $totalBalance += $balance;
}

echo "\n";

//колонка СРЕДНЕЕ
echo padRight("Среднее", $col1) .
    padLeft($totalBodies/4, $col2) .
    padLeft($totalSalary/4, $col2) .
    padLeft($totalCoffee/4, $col2) .
    padLeft($totalPages/4, $col2) .
    padLeft($totalBalance/4, $col2) .
    "\n";

//колонка ВСЕГО
echo padRight("Всего", $col1) .
    padLeft($totalBodies, $col2) .
    padLeft($totalSalary, $col2) .
    padLeft($totalCoffee, $col2) .
    padLeft($totalPages, $col2) .
    padLeft($totalBalance, $col2) .
    "\n";