<?php

namespace Velis\User;

use Exception;
use User\User;
use Velis\Exception\BusinessLogicException;
use Velis\Lang;

/**
 * Registered user absence
 * @author Olek Procki <olo@velis.pl>
 */
class Duty extends Absence
{
    /**
     * {@inheritDoc}
     */
    public static function getList($page = 1, $params = null, $order = null, $limit = self::ITEMS_PER_PAGE, $fields = null)
    {
        if ($params['date_from']) {
            if ($params['h_from']) {
                $date_from = $params['date_from'] . ' ' . str_replace('T', '', $params['h_from']);
            } else {
                $date_from = $params['date_from'];
            }
            self::$_listConditions[] = "date_trunc('day', date_from) >= :date_from";
            self::$_listParams['date_from'] = $date_from;
            unset($params['date_from']);
            $params['archive'] = 1;
        }

        if ($params['date_to']) {
            if ($params['h_to']) {
                $date_to = $params['date_to'] . ' ' . str_replace('T', '', $params['h_to']);
            } else {
                $date_to = $params['date_to'];
            }
            self::$_listConditions[] = "date_trunc('day', date_to) <= :date_to::date + INTERVAL '1 day'";
            self::$_listParams['date_to'] = $date_to;

            unset($params['date_to']);
            $params['archive'] = 1;
        }

        if ($params['building_complex_id']) {
            self::$_listConditions[] = "user_id IN (SELECT user_id
                                                      FROM acl.user u
                                                     WHERE ARRAY[:building_complex_id::integer] && u.building_complex_array)";
            self::$_listParams['building_complex_id'] = $params['building_complex_id'];
        }

        return parent::getList($page, $params, $order, $limit, $fields);
    }


    /**
     * Validates absence dates
     * @throws BusinessLogicException
     */
    protected function _checkConflict()
    {
        if ($this->_conflictsChecked) {
            return $this;
        }

        $query = "SELECT COUNT(*) FROM acl.user_absence_tab
                    WHERE user_id=:user_id
                      AND user_absence_id != COALESCE(:user_absence_id,0)
                      AND (:date_from BETWEEN date_from AND date_to
                           OR :date_to BETWEEN date_from AND date_to
                           OR (:date_from < date_from AND :date_to > date_to))";

        $params = $this->getArrayCopy();
        unset(
            $params['is_emergency'],
            $params['building_complex_shift_id'],
            $params['unqualified_employee']
        );

        if (!$this->id()) {
            $params['user_absence_id'] = null;
        }
        if (self::$_db->getOne($query, $params)) {
            throw new BusinessLogicException(Lang::get('USER_ABSENCE_DATE_OVERLAPS'));
        }
        $this->_conflictsChecked = 1;
        return $this;
    }


    /**
     * {@inheritDoc}
     */
    public function add($updateObjectId = true)
    {
        return parent::add(true);
    }


    /**
     * {@inheritDoc}
     */
    public function modify($checkDiff = false)
    {
        return parent::modify();
    }


    /**
     * {@inheritDoc}
     */
    public function save($updateObjectId = false)
    {
        $day = $this['date_from'];

        $this['date_from'] = date('Y-m-d H:i:s', strtotime('+' . $this['time_from'] . ' minutes', strtotime($day)));
        $this['date_to']   = $this['time_from'] > $this['time_to'] ? date('Y-m-d H:i:s', strtotime('+1 day', strtotime($day))) : $day;
        $this['date_to']   = date('Y-m-d H:i:s', strtotime('+' . $this['time_to'] . ' minutes', strtotime($this['date_to'])));
        $this['is_emergency'] = $this['is_emergency'] ? 1 : 0;
        $this->sanitize();

        $this->_checkConflict();

        if ($this->id()) {
            $this['building_complex_shift_id'] = null;
        }

        User::unsetListCache();

        return parent::save();
    }


    /**
     * Remove absence list
     * @param int[] $ids
     * @throws Exception
     */
    public static function removeList($ids)
    {
        try {
            self::$_db->startTrans();

            foreach ($ids as $id) {
                $duty = new Duty($id);
                $duty->_remove();
            }

            User::unsetListCache();
            self::$_db->commit();
        } catch (Exception $ex) {
            self::$_db->rollback();
            throw $ex;
        }
    }
}
