<?php

class AdvancedQueueReport extends PhonalisaRecord
{

    public $incommingCalls = 0;
    public $acceptedCalls = 0;
    public $missedCalls = 0;
    public $averageLatencyTime = 0;
    public $averageCallDuration = 0;
    public $readyTime = 0;
    public $callTime = 0;
    public $waitTime = 0;
    public $successRate = 0;
    public $loginLogoutTime = '';
    private $timeRange = '';
    private $timePickerValue = '';
    private $defaultStartTime = '';
    private $defaultEndTime = '';

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Job the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return strtolower('AdvancedQueueReport');
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'agent' => __('ADVANCED_QUEUE_REPORT_AGENT'),
            'incommingCalls' => __('ADVANCED_QUEUE_REPORT_INCOMMING_CALLS'),
            'acceptedCalls' => __('ADVANCED_QUEUE_REPORT_ACCEPTED_CALLS'),
            'missedCalls' => __('ADVANCED_QUEUE_REPORT_MISSED_CALLS'),
            'averageLatencyTime' => __('ADVANCED_QUEUE_REPORT_AVERAGE_LATENCY_TIME'),
            'averageCallDuration' => __('ADVANCED_QUEUE_REPORT_AVERAGE_CALL_DURATION'),
            'readyTime' => __('ADVANCED_QUEUE_REPORT_READY_TIME'),
            'callTime' => __('ADVANCED_QUEUE_REPORT_CALL_TIME'),
            'successRate' => __('ADVANCED_QUEUE_REPORT_SUCCESS_RATE')
        );
    }

    protected function resetEventTimes()
    {
        $this->incommingCalls = 0;
        $this->acceptedCalls = 0;
        $this->missedCalls = 0;
        $this->averageLatencyTime = 0;
        $this->averageCallDuration = 0;
        $this->readyTime = 0;
        $this->waitTime = 0;
        $this->callTime = 0;
        $this->successRate = 0;
        $this->loginLogoutTime = '';
    }

    protected function setSuccessRate()
    {
        if (!empty($this->incommingCalls)) {
            $this->successRate = round(($this->acceptedCalls / $this->incommingCalls) * 100, 2);
        }
    }

    public function getQueueReportData($queueModel, $timeRange, $timePickerValue)
    {
        $this->timeRange = $timeRange;
        $this->timePickerValue = $timePickerValue;
        $this->setDefaultDateTimes();

        $attributes = $this->getSearchAttributesForStatistic($queueModel->id);
        $model = Statistic::model()->findByAttributes($attributes);

        $name = __('ADVANCED_QUEUE_REPORT_FULL_QUEUE_TEXT');
        if ($model) {
            $this->acceptedCalls = (int) $model->counter_success;
            $this->missedCalls = (int) $model->getAllMissedCalls();
            $this->incommingCalls = (int) $this->acceptedCalls + (int) $this->missedCalls;
        }
        $data = $this->getDataArray(array(), 'queue', $queueModel->id, $name);
        return $this->processQueueAgentsData($data);
    }

    protected function setDefaultDateTimes()
    {
        if ($this->timeRange == Statistic::StatisticTimeRangeTypeYear) {
            $this->processStatisticRangeYear();
        } else if ($this->timeRange == Statistic::StatisticTimeRangeTypeMonth) {
            $this->processStatisticRangeMonth();
        } else if ($this->timeRange == Statistic::StatisticTimeRangeTypeWeek) {
            $this->processStatisticRangeWeek();
        } else {
            $this->processStatisticRangeDay();
        }
    }

    protected function processStatisticRangeYear()
    {
        $newServerDate = PhonalisaDate::newServerDate();
        $dateTime = PhonalisaDate::convertServerDateTo('Y', PhonalisaDate::newServerDate($this->timePickerValue, 'Y'));
        $currentTime = PhonalisaDate::convertServerDateTo('Y', $newServerDate, true);

        $this->defaultStartTime = $dateTime . '-01-01 00:00:00';
        if ($dateTime != $currentTime) {
            $this->defaultEndTime = $dateTime . '-12-31 23:59:59';
        } else {
            $this->defaultEndTime = PhonalisaDate::convertServerDateTo('Y-m-d H:i:s', $newServerDate, true);
        }
    }

    protected function processStatisticRangeMonth()
    {
        $timePickerValue = PhonalisaDate::newServerDate($this->timePickerValue, 'm.Y');
        $newServerDate = PhonalisaDate::newServerDate();
        $dateTime = PhonalisaDate::convertServerDateTo('Y-m', $timePickerValue);
        $currentTime = PhonalisaDate::convertServerDateTo('Y-m', $newServerDate, true);
        $dateTimeWithLastDayOfMonth = PhonalisaDate::convertServerDateTo('Y-m-t', $timePickerValue);
        $currentTimeWithMonth = PhonalisaDate::convertServerDateTo('Y-m-d', $newServerDate, true);

        $this->defaultStartTime = PhonalisaDate::convertServerDateTo('Y-m', $timePickerValue) . '-01 00:00:00';
        if ($dateTime != $currentTime && $dateTimeWithLastDayOfMonth != $currentTimeWithMonth) {
            $this->defaultEndTime = $dateTimeWithLastDayOfMonth . ' 23:59:59';
        } else {
            $this->defaultEndTime = PhonalisaDate::convertServerDateTo('Y-m-d H:i:s', $newServerDate, true);
        }
    }

    protected function processStatisticRangeWeek()
    {
        $pattern = 'Y-m-d';
        $explDate = explode('_', $this->timePickerValue);
        $date = new DateTime();
        $date->setISODate($explDate[1], $explDate[0]);
        $startDate = PhonalisaDate::newServerDate($date->format($pattern), $pattern);
        $searchStartDate = PhonalisaDate::convertServerDateTo($pattern, $startDate, true);
        $date->setISODate($explDate[1], $explDate[0], 7);
        $endDate = PhonalisaDate::newServerDate($date->format($pattern), $pattern);
        $searchEndDate = PhonalisaDate::convertServerDateTo($pattern, $endDate, true);
        $newServerDate = PhonalisaDate::newServerDate();
        $searchDateTime = PhonalisaDate::convertServerDateTo('W_Y', $newServerDate, true);
        $currentDateTime = PhonalisaDate::convertServerDateTo($pattern, $newServerDate, true);

        $this->defaultStartTime = $searchStartDate . ' 00:00:00';
        if ($searchDateTime != $this->timePickerValue && $searchEndDate != $currentDateTime) {
            $this->defaultEndTime = $searchEndDate . ' 23:59:59';
        } else {
            $this->defaultEndTime = PhonalisaDate::convertServerDateTo('Y-m-d H:i:s', $newServerDate, true);
        }
    }

    protected function processStatisticRangeDay()
    {
        $newServerDate = PhonalisaDate::newServerDate();
        $dateTime = PhonalisaDate::convertServerDateTo('Y-m-d', PhonalisaDate::newServerDate($this->timePickerValue, 'd.m.Y'));
        $currentTime = PhonalisaDate::convertServerDateTo('Y-m-d', $newServerDate, true);

        $this->defaultStartTime = $dateTime . ' 00:00:00';
        if ($dateTime != $currentTime) {
            $this->defaultEndTime = $dateTime . ' 23:59:59';
        } else {
            $this->defaultEndTime = PhonalisaDate::convertServerDateTo('Y-m-d H:i:s', $newServerDate, true);
        }
    }

    protected function processQueueAgentsData($data)
    {
        $data['agent'] = $this->getAgentsData($data);
        foreach ($data['agent'] as $agent) {
            $data['queue']['waitTime']+= $agent['waitTime'];
            $data['queue']['callTime']+= $agent['callTime'];
        }

        if ((int) $data['queue']['acceptedCalls'] >= 1) {
            $data['queue']['averageCallDuration'] = abs(round((int) $data['queue']['callTime'] / (int) $data['queue']['acceptedCalls']));
            $data['queue']['averageLatencyTime'] = abs(round((int) $data['queue']['waitTime'] / (int) $data['queue']['acceptedCalls']));
        }
        return $data;
    }

    protected function getDataArray($data, $key, $id, $name)
    {
        $data[$key]['id'] = $id;
        $data[$key]['name'] = $name;
        $data[$key]['incommingCalls'] = $this->incommingCalls;
        $data[$key]['acceptedCalls'] = $this->acceptedCalls;
        $data[$key]['missedCalls'] = $this->missedCalls;
        $data[$key]['averageLatencyTime'] = $this->averageLatencyTime;
        $data[$key]['averageCallDuration'] = $this->averageCallDuration;
        $data[$key]['readyTime'] = $this->readyTime;
        $data[$key]['waitTime'] = $this->waitTime;
        $data[$key]['callTime'] = $this->callTime;
        $data[$key]['loginLogoutTime'] = $this->loginLogoutTime;
        $this->setSuccessRate();
        $data[$key]['successRate'] = $this->successRate;
        $this->resetEventTimes();
        return $data;
    }

    protected function getSearchAttributesForStatistic($queueID)
    {
        $attributes = array(
            'time_range_type' => $this->timeRange,
            'target_type' => Statistic::StatisticTargetTypeQueue,
            'target_id' => $queueID,
        );

        if ($this->timeRange == Statistic::StatisticTimeRangeTypeYear) {
            $attributes['year'] = $this->timePickerValue;
        } elseif ($this->timeRange == Statistic::StatisticTimeRangeTypeMonth) {
            $datetime = PhonalisaDate::newServerDate($this->timePickerValue, 'm.Y');
            $attributes['month'] = ltrim(PhonalisaDate::convertServerDateTo('m', $datetime, true), '0');
            $attributes['year'] = PhonalisaDate::convertServerDateTo('Y', $datetime, true);
        } elseif ($this->timeRange == Statistic::StatisticTimeRangeTypeWeek) {
            $datetime = explode('_', $this->timePickerValue);
            $attributes['week'] = ltrim($datetime[0], '0');
            $attributes['year'] = $datetime[1];
        } elseif ($this->timeRange == Statistic::StatisticTimeRangeTypeDay) {
            $datetime = PhonalisaDate::newServerDate($this->timePickerValue, 'd.m.Y');
            $attributes['year'] = PhonalisaDate::convertServerDateTo('Y', $datetime, true);
            $attributes['day'] = (int) PhonalisaDate::convertServerDateTo('z', $datetime, true) + 1;
        }
        return $attributes;
    }

    public function getAgentsData($queueData)
    {
        $data = array();
        $queue_id = $queueData['queue']['id'];
        $attributes = $this->getSearchAttributesForStatistic($queue_id);
        $attributes['target_type'] = Statistic::StatisticTargetTypeAgentInbound;
        $statisticModels = Statistic::model()->findAllByAttributes($attributes);

        foreach ($statisticModels as $model) {
            $agent_id = $model->valueForKey('agent_id', '');
            if (empty($agent_id)) {
                continue;
            }
            $this->processStatisticTimes($model);
            $this->updateAgentReadyTime($queue_id, $agent_id);
            $formatedName = $this->getFormatedAgentName($agent_id);
            $data = $this->getDataArray($data, $formatedName, $agent_id, $formatedName);
        }
        return $data;
    }

    protected function updateAgentReadyTime($queue_id, $agent_id)
    {
        $tierModel = Tiers::model()->findByAttributes(array('queueId' => $queue_id, 'userId' => $agent_id));
        if ($tierModel) {
            if ($tierModel->static_member == '1') {
                $this->readyTime = 'n/a';
                $this->loginLogoutTime = __('ADVANCED_QUEUE_REPORT_STATIC_MEMBER');
                return;
            }

            $type = $tierModel->valueForKey('lastAction', '');
            $lastLoginLogoutDateTime = PhonalisaDate::convertServerDateTo('Y-m-d H:i:s', $tierModel->valueForKey('lastloginlogout', ''), true);
            $startTime = $this->getStartTimeInRange($lastLoginLogoutDateTime);
            if ($type == 'login' && $startTime != '' && $this->isValidStartTime($startTime)) {
                $this->readyTime+= abs((int) PhonalisaDate::convertServerDateTo('U', $startTime) - (int) PhonalisaDate::convertServerDateTo('U', $this->defaultEndTime));
            }
            $this->setFormatedLoginLogoutTime($lastLoginLogoutDateTime, $type);
        }
    }

    protected function isValidStartTime($startTime)
    {
        $result = false;
        if ($startTime != $this->defaultStartTime) {
            $result = true;
        }
        return $result;
    }

    protected function getStartTimeInRange($datetime)
    {
        $result = $this->defaultStartTime;
        if ($this->timeRange == Statistic::StatisticTimeRangeTypeYear && PhonalisaDate::convertServerDateTo('Y', $datetime, true) == $this->timePickerValue) {
            $result = $datetime;
        } else if ($this->timeRange == Statistic::StatisticTimeRangeTypeMonth && PhonalisaDate::convertServerDateTo('m.Y', $datetime, true) == $this->timePickerValue) {
            $result = $datetime;
        } else if ($this->timeRange == Statistic::StatisticTimeRangeTypeWeek && PhonalisaDate::convertServerDateTo('W_Y', $datetime, true) == $this->timePickerValue) {
            $result = $datetime;
        } else if ($this->timeRange == Statistic::StatisticTimeRangeTypeDay && PhonalisaDate::convertServerDateTo('d.m.Y', $datetime, true) == $this->timePickerValue) {
            $result = $datetime;
        }
        return $result;
    }

    protected function setFormatedLoginLogoutTime($datetime, $type)
    {
        $text = __('ADVANCED_QUEUE_REPORT_LAST_LOGIN_LOGOUT_TOOLTIP');
        $this->loginLogoutTime = __($text, true, 'messages', array("{type}" => ucfirst($type), "{datetime}" => $datetime));
    }

    protected function processStatisticTimes($model)
    {
        if ($model) {
            $this->acceptedCalls = (int) $model->counter_success;
            $this->missedCalls = (int) $model->getAllMissedCalls();
            $this->callTime = (int) $model->valueForKey('duration', 0);
            $this->incommingCalls = (int) $this->acceptedCalls + (int) $this->missedCalls;
            $this->readyTime = (int) $model->valueForKey('ready_time', 0);
            $this->waitTime = (int) $model->valueForKey('wait_time', 0);
            if ((int) $this->acceptedCalls >= 1) {
                $this->averageCallDuration = abs(round((int) $this->callTime / (int) $this->acceptedCalls));
                $this->averageLatencyTime = abs(round((int) $this->waitTime / (int) $this->acceptedCalls));
            }
        }
    }

    protected function getFormatedAgentName($agentID)
    {
        $name = __('ADVANCED_QUEUE_REPORT_DELETED_USER') . "_$agentID";
        $model = User::model()->findByPk($agentID);
        if ($model) {
            $name = getFormatedUsername($model);
        }
        return $name;
    }

    public function getFormatedQueueName($data)
    {
        $name = @$data->name;
        $extension = @$data->extension;
        $formatedName = '';

        if (isset($extension) && $extension !== '') {
            $formatedName.= "<$extension>";
        }

        if (isset($name) && $name !== '') {
            $formatedName.= " " . CHtml::encode($name);
        }
        return trim($formatedName);
    }

    public function getDataProvider($overviewData)
    {
        $data = array();
        $data[0]['id'] = $overviewData['queue']['id'];
        $data[0]['name'] = __('ADVANCED_QUEUE_REPORT_FULL_QUEUE_TEXT');
        $data[0]['incommingCalls'] = $overviewData['queue']['incommingCalls'];
        $data[0]['acceptedCalls'] = $overviewData['queue']['acceptedCalls'];
        $data[0]['missedCalls'] = $overviewData['queue']['missedCalls'];
        $data[0]['averageLatencyTime'] = $overviewData['queue']['averageLatencyTime'];
        $data[0]['averageCallDuration'] = $overviewData['queue']['averageCallDuration'];
        $data[0]['readyTime'] = '';
        $data[0]['callTime'] = $overviewData['queue']['callTime'];
        $data[0]['successRate'] = $overviewData['queue']['successRate'];
        $data[0]['loginLogoutTime'] = '';

        $key = $deletedUserCount = 1;
        foreach ($overviewData['agent'] as $value) {
            $name = $value['name'];
            if (startsWith($name, __('ADVANCED_QUEUE_REPORT_DELETED_USER') . '_')) {
                $name = __('ADVANCED_QUEUE_REPORT_DELETED_USER') . " $deletedUserCount";
                $deletedUserCount++;
            }

            $data[$key]['id'] = $key;
            $data[$key]['name'] = $name;
            $data[$key]['incommingCalls'] = $value['incommingCalls'];
            $data[$key]['acceptedCalls'] = $value['acceptedCalls'];
            $data[$key]['missedCalls'] = $value['missedCalls'];
            $data[$key]['averageLatencyTime'] = $value['averageLatencyTime'];
            $data[$key]['averageCallDuration'] = $value['averageCallDuration'];
            $data[$key]['readyTime'] = $value['readyTime'];
            $data[$key]['callTime'] = $value['callTime'];
            $data[$key]['successRate'] = $value['successRate'];
            $data[$key]['loginLogoutTime'] = $value['loginLogoutTime'];
            $key++;
        }
        $dataProvider = new CArrayDataProvider($data, array(
            'pagination' => false
        ));
        return $dataProvider;
    }
}
