/Vector/Notify.pm
package Vector::Notify;
use Mail::Message;
use Vector::DB;
use Vector::Util;
use Vector::Channel;
use Vector::User;
use Vector::HtmlFilter;
use strict;

sub get {
	my ($user_id, $channel_id, $thread) = @_;
	my $dbh = Vector::DB::connect;

	my $watch_id;
	if (defined $thread) {
		($watch_id) = $dbh->selectrow_array('SELECT watch_id FROM watch WHERE user_id = ? AND channel_id = ? AND thread = ?', undef, $user_id, $channel_id, $thread);
	} else {
		($watch_id) = $dbh->selectrow_array('SELECT watch_id FROM watch WHERE user_id = ? AND channel_id = ? AND thread IS NULL', undef, $user_id, $channel_id);
	}

	return $watch_id;
}

sub set {
	my ($user_id, $channel_id, $thread) = @_;
	my $dbh = Vector::DB::connect;

	if (defined $thread) {
		$dbh->do('INSERT INTO watch (user_id, channel_id, thread) VALUES (?,?,?)', undef, $user_id, $channel_id, $thread)
			or die $dbh->errstr;
	} else {
		$dbh->do('INSERT INTO watch (user_id, channel_id) VALUES (?,?)', undef, $user_id, $channel_id)
			or die $dbh->errstr;
	}

	# Icky icky icky
	my ($watch_id) = $dbh->selectrow_array('SELECT LAST_INSERT_ID()');
}

sub clear {
	my ($user_id, $channel_id, $thread) = @_;
	my $dbh = Vector::DB::connect;

	if (defined $thread) {
		$dbh->do('DELETE FROM watch WHERE user_id = ? AND channel_id = ? AND thread = ?', undef, $user_id, $channel_id, $thread);
	} else {
		$dbh->do('DELETE FROM watch WHERE user_id = ? AND channel_id = ? AND thread IS NULL', undef, $user_id, $channel_id);
	}
}

sub widget {
	my ($user_id, $channel_id, $thread) = @_;

	my $type;
	if (defined $thread) {
		$type = 'thread';
	} else {
		$type = 'channel';
	}

	if (Vector::Notify::get($user_id, $channel_id, $thread)) {
		return qq{You are currently getting email notifications for activity in this $type. <a href="?watch=off">Turn off notifications</a>.};
	} else {
		return qq{<a href="?watch=on">Turn on email notifications</a> for this $type.};
	}
}

sub queue {
	my ($message, $channel_id, $thread) = @_;
	my $dbh = Vector::DB::connect;
	my $sth;
	my %watchers;

	Vector::HtmlFilter::textify \$message;

	# Queue for everyone watching this thread
	$sth = $dbh->prepare('SELECT users.user_id, users.email FROM watch LEFT JOIN users ON users.user_id = watch.user_id WHERE channel_id = ? AND thread = ?');
	$sth->execute($channel_id, $thread);
	while (my $row = $sth->fetchrow_hashref) {
		next unless $row->{email};
		$dbh->do('INSERT INTO notify (user_id, message) VALUES (?,?)', undef, $row->{user_id}, $message);
		$watchers{$row->{user_id}}++;
	}

	# Queue for everyone watching this channel
	$sth = $dbh->prepare('SELECT users.user_id, users.email FROM watch LEFT JOIN users ON users.user_id = watch.user_id WHERE channel_id = ? AND thread IS NULL');
	$sth->execute($channel_id);
	while (my $row = $sth->fetchrow_hashref) {
		next unless $row->{email};
		next if exists $watchers{$row->{user_id}};	# Don't notify twice
		$dbh->do('INSERT INTO notify (user_id, message) VALUES (?,?)', undef, $row->{user_id}, $message)
			or die $dbh->errstr;
	}
}

sub send {
	my ($user_id) = @_;
	my $dbh = Vector::DB::connect;
	my (@ids, @messages);

	my $user = Vector::User->fetch_by_id($user_id);
	my $dname = Vector::Util::simplify_uri($user->{username});
	my $to = qq{"$dname" <$user->{email}>};

	my $sth = $dbh->prepare('SELECT notify_id, message FROM notify WHERE user_id = ?');
	$sth->execute($user_id);
	while (my $row = $sth->fetchrow_hashref) {
		push @ids, $row->{notify_id};
		push @messages, $row->{message};
	}

	my $msg = Mail::Message->build(
		To => $to,
		From => 'Vector <vector@dominionofawesome.com>',
		Subject => @messages . ' new messages on Vector',
		data => <<EOD . join("\n\n", @messages),
When replying, make sure that the reply tag remains in your reply.

EOD
	);

	$msg->send;

	$dbh->begin_work;
	foreach my $id (@ids) {
		$dbh->do('DELETE FROM notify WHERE notify_id = ?', undef, $id);
	}
	$dbh->commit;
}

sub send_all {
	my $dbh = Vector::DB::connect;

	my $users = $dbh->selectcol_arrayref('SELECT DISTINCT user_id FROM notify');
	foreach my $u (@$users) {
		Vector::Notify::send($u);
	}
}

1;