#!/usr/bin/env perl
use strict;
use warnings;
use FindBin qw($RealBin);
use lib "$RealBin/../lib";

# Webhook receiver — Mojolicious::Lite app.
# Binds to 127.0.0.1 only; nginx terminates TLS and proxies inbound updates.
#
# Startup:
#   mnemosyne-bot --config /path/to/mnemosyne.conf
#   mnemosyne-bot --config /path/to/mnemosyne.conf daemon  (same, explicit)
#
# In production (systemd), the unit sets:
#   ExecStart=/usr/bin/perl /opt/mnemosyne/bin/mnemosyne-bot --config /etc/mnemosyne/mnemosyne.conf

use Mnemosyne::Config;
use Mnemosyne::DB;
use Mnemosyne::Telegram;
use Mnemosyne::Webhook;
use Mojolicious::Lite;

# ---- parse --config before Mojolicious sees ARGV ----------------------
my $config_path = "$RealBin/../config/mnemosyne.conf";
my @passthrough;
while (@ARGV) {
    my $arg = shift @ARGV;
    if ($arg eq '--config' && @ARGV) {
        $config_path = shift @ARGV;
    } else {
        push @passthrough, $arg;
    }
}
@ARGV = @passthrough;

# ---- load config & bootstrap ------------------------------------------
die "Config file not found: $config_path\n" unless -f $config_path;
my $config   = Mnemosyne::Config->new($config_path);
my $db       = Mnemosyne::DB->new($config->get('db', 'path'));
my $token    = $config->get('bot', 'token')         or die "bot.token missing in config\n";
my $secret   = $config->get('bot', 'webhook_secret') or die "bot.webhook_secret missing in config\n";
my $port     = $config->get('bot', 'listen_port') // 8443;
my $wh_url   = $config->get('bot', 'webhook_url')    or die "bot.webhook_url missing in config\n";

my $telegram = Mnemosyne::Telegram->new($token);

# Extract the path component from the webhook URL
# e.g. https://example.com/tghook/abc123  →  /tghook/abc123
(my $wh_path = $wh_url) =~ s{^https?://[^/]+}{};
$wh_path ||= '/webhook';

# ---- webhook endpoint -------------------------------------------------
post $wh_path => sub {
    my ($c) = @_;

    # Gate 1: validate Telegram's secret-token header
    my $incoming_secret = $c->req->headers->header('X-Telegram-Bot-Api-Secret-Token') // '';
    unless ($incoming_secret eq $secret) {
        $c->render(text => 'Forbidden', status => 403);
        return;
    }

    # Respond 200 immediately — Telegram retries on non-2xx or timeouts
    $c->render(text => 'ok', status => 200);

    # Process the update (synchronous; fast enough for single-user load)
    my $update = $c->req->json;
    eval {
        Mnemosyne::Webhook->handle_update($update, $db, $config, $telegram);
    };
    warn "Webhook processing error: $@\n" if $@;
};

# ---- start ------------------------------------------------------------
# Default to daemon on localhost; let explicit ARGV override for hypnotoad etc.
push @ARGV, ('daemon', '-l', "http://127.0.0.1:$port") unless @ARGV;

app->start;
