<?php

class Subscriber
{
	public function __construct()
	{
		$this->send_limit=config::get('core.subscriber_limit');
		if (!$this->send_limit) $this->send_limit=30;
	}
	
	public function addMessage($message, $item_id)
	{
		Db::i()->query("INSERT INTO ?_subscribe_status (`text`, item_id) VALUES(?, ?)", serialize($message), $item_id);
		$this->_unblockMailing();
	}
	
	public function subscribe($item_id, $user_id=null)
	{
		if (!$user_id) $user_id=User::i()->id;
		Db::i()->query("INSERT IGNORE INTO ?_subscribe (user_id, item_id) VALUES(?, ?)", $user_id, $item_id);
	}
	
	public function unsubscribe($item_id, $user_id=null)
	{
		if (!$user_id) $user_id=User::i()->id;
		Db::i()->query("DELETE FROM ?_subscribe WHERE user_id=? AND item_id=?", $user_id, $item_id);
	}
	
	public function getSubscribeStatus($item_id, $user_id=null)
	{
		if (!$user_id) $user_id=User::i()->id;
		return Db::i()->selectCell("SELECT count(*) FROM ?_subscribe WHERE user_id=? AND item_id=?", $user_id, $item_id);
	}
	
	public function send()
	{
		if ($this->_isLocked() || $this->_isBlocked()) return;
		$this->_setLock();
		$this->_send();
		$this->_removeLock();
	}
	
	protected function _send()
	{
		if (!$status=Db::i()->selectRow("SELECT * FROM ?_subscribe_status ORDER BY id LIMIT 1")) {
			$this->_blockMailing();
			return;
		}
		
		$users=Db::i()->select(
			"SELECT s.user_id, email, login
			FROM ?_subscribe s JOIN ?_users u ON s.user_id=u.user_id
			WHERE item_id=? AND s.user_id>?d ORDER BY s.user_id LIMIT ?d",
			$status['item_id'], $status['last_user_id'], $this->send_limit
		);
		
		$message=unserialize($status['text']);
		
		if (!empty($message['exclude']) && !is_array($message['exclude'])) $message['exclude']=array($message['exclude']);
		elseif(empty($message['exclude'])) $message['exclude']=array();
		//тут отправляем письма
		if ($users) {
			foreach ($users as $user) {
				if (in_array($user['user_id'], $message['exclude'])) continue;
				$message['to']=array($user['email']=>$user['login']);
				$this->_sendMail($message);
			}
		}
		
		//обновляем статус отправки или удаляем задание
		if ($this->send_limit-count($users)) {
			Db::i()->query("DELETE FROM ?_subscribe_status WHERE id=?", $status['id']);
		} else {
			Db::i()->query("UPDATE ?_subscribe_status SET last_user_id=? WHERE id=?", $status['id']);
		}
		
		if ($this->send_limit) {
			$this->_send();
		}
	}
	
	protected function _sendMail($message)
	{
		$mail=Factory::create('Mailer', $message['to']);
		$mail->From = $message['from']?$message['from']:'robot@'.config::get('core.domain');
		$mail->FromName = $message['fromName']?$message['fromName']:"Робот сайта";
		$mail->AddReplyTo($mail->From, $mail->FromName);
		$mail->WordWrap = 80;
		$mail->Subject = $message['subject'];
		$mail->Body = $message['text'];
		$mail->IsHTML($message['isHtml']);
		$mail->Send();
	}
	
	protected function _setLock()
	{
		TCache::set(true, 'subscribe_lock', null, 30);
	}
	
	protected function _removeLock()
	{
		TCache::remove('subscribe_lock');
	}
	
	protected function _isLocked()
	{
		return TCache::get('subscribe_lock');
	}
	
	protected function _blockMailing()
	{
		TCache::set(true, 'subscribe_blocked', null);
	}
	
	protected function _unblockMailing()
	{
		TCache::remove('subscribe_blocked');
	}
	
	protected function _isBlocked()
	{
		return TCache::get('subscribe_blocked');
	}
	
}