#! /usr/bin/perl
use strict;
use warnings;
no warnings qw(once);
use Crypt::JWT;
use JSON::XS;
use LWP::UserAgent;
use DBI;
use POSIX;
use Time::HiRes;
use IO::Select;
use Unicode::Collate;
use IO::Socket::SSL;
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';
use utf8;

require '../include/config.pm';

my $global_ctx = IO::Socket::SSL::SSL_Context->new(
	SSL_session_cache_size => 100,  # Probably overkill.
);
IO::Socket::SSL::set_default_context($global_ctx);

sub get_slack_name {
	my ($ua, $userid) = @_;
	my $req = HTTP::Request->new('GET', 'https://slack.com/api/users.info?user=' . $userid, [
	       'Authorization' => 'Bearer ' . $config::slack_oauth_token
	]);
	my $start = [Time::HiRes::gettimeofday];
	my $response = $ua->request($req);
	log_timing($start, '/users.info');
	die $response->status_line if !$response->is_success;

	my $user_json = JSON::XS::decode_json($response->decoded_content);
	die "Something went wrong: " . $response->decoded_content if (!defined($user_json) || !$user_json->{'ok'});

	return $user_json->{'user'}{'real_name'};
}

sub db_connect {
	my $dbh = DBI->connect("dbi:Pg:dbname=$config::dbname;host=127.0.0.1", $config::dbuser, $config::dbpass, {RaiseError => 1})
		or warn "Could not connect to Postgres: " . DBI->errstr;
	if (!defined($dbh)) {
		return undef;
	}
	$dbh->{AutoCommit} = 0;
	$dbh->do('LISTEN skvupdate') or return undef;
	return $dbh;
}

my $channel = $ARGV[1] // 'C06C34L2R6G';
my $ts = $ARGV[2] // '1712686401.430939';

my $dbh = db_connect() or die;
my $ua = LWP::UserAgent->new(agent => 'SKVidarLang/1.0', keep_alive => 50);
$dbh->do('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');

my $req = HTTP::Request->new('GET', 'https://slack.com/api/reactions.get?channel=' . $channel . '&timestamp=' . $ts . '&full=true', [
       'Authorization' => 'Bearer ' . $config::slack_oauth_token
]);
my $start = [Time::HiRes::gettimeofday];
my $response = $ua->request($req);
die $response->status_line if !$response->is_success;

my $user_json = JSON::XS::decode_json($response->decoded_content);
die "Something went wrong: " . $response->decoded_content if (!defined($user_json) || !$user_json->{'ok'});

#print  $response->decoded_content, "\n";

my $q = $dbh->prepare('SELECT COUNT(*) AS num FROM current_reactions WHERE channel=? AND ts=? AND userid=? AND reaction=?');
for my $reaction (@{$user_json->{'message'}{'reactions'}}) {
	my $name = $reaction->{'name'};
	for my $user (@{$reaction->{'users'}}) {
		$q->execute($channel, $ts, $user, $name);
		my $ref = $q->fetchrow_hashref;
		if ($ref->{'num'} == 0) {
			$dbh->do('INSERT INTO reaction_log (userid, channel, ts, event_type, event_ts, reaction) VALUES (?, ?, ?, ?, ?, ?)',
				undef, $user, $channel, $ts, 'reaction_added', time, $name);
			print "$name $user\n";
		}
	}
}

$dbh->commit;
$dbh->do('NOTIFY skvupdate');
$dbh->commit;
