#!/usr/local/cpanel/3rdparty/bin/perl
# gniza4cp cPanel Plugin — Activity Logs
# Shows user-initiated restore actions and their results
use strict;
use warnings;

BEGIN {
    my $base;
    if ($0 =~ m{^(.*)/}) {
        $base = $1;
    } else {
        $base = '.';
    }
    unshift @INC, "$base/lib";
}

use Cpanel::LiveAPI ();
use Cpanel::AdminBin::Call ();
use Cpanel::Form           ();
use Gniza4cpCPanel::UI;

my $cpanel = Cpanel::LiveAPI->new();
END { $cpanel->end() if $cpanel }
my $form = Cpanel::Form::parseform();
my $entry = $form->{'entry'} // '';

if ($entry ne '') {
    show_entry($entry);
} else {
    show_list();
}

exit;

# ── List View ────────────────────────────────────────────────

sub show_list {
    print "Content-Type: text/html\r\n\r\n";
    print $cpanel->header('');
    print Gniza4cpCPanel::UI::page_header('GNIZA Activity Log');
    print Gniza4cpCPanel::UI::render_nav('logs.live.cgi');
    print Gniza4cpCPanel::UI::render_flash();

    my $raw = eval { Cpanel::AdminBin::Call::call('Gniza4cp', 'Restore', 'LIST_LOGS') } // '';

    if ($raw =~ /^ERROR: (.*)/) {
        print qq{<div class="alert alert-error mb-4">} . Gniza4cpCPanel::UI::esc($1) . qq{</div>\n};
        print Gniza4cpCPanel::UI::page_footer();
        print $cpanel->footer();
        return;
    }

    my @entries;
    for my $line (split /\n/, $raw) {
        next if $line eq '';
        my ($idx, $date, $action, $details, $status) = split /\t/, $line;
        push @entries, {
            idx     => $idx     // '',
            date    => $date    // '',
            action  => $action  // '',
            details => $details // '',
            status  => $status  // '',
        };
    }

    if (!@entries) {
        print qq{<div class="alert alert-info mb-4">No restore activity yet. Actions you perform in the Restore section will appear here.</div>\n};
        print Gniza4cpCPanel::UI::page_footer();
        print $cpanel->footer();
        return;
    }

    # Pagination
    my $per_page    = 25;
    my $total       = scalar @entries;
    my $page        = int($form->{'page'} // 1);
    $page = 1 if $page < 1;
    my $total_pages = int(($total + $per_page - 1) / $per_page);
    $page = $total_pages if $page > $total_pages;
    my $start = ($page - 1) * $per_page;
    my $end   = $start + $per_page - 1;
    $end = $#entries if $end > $#entries;
    my @page_entries = @entries[$start .. $end];

    print qq{<div class="overflow-x-auto rounded-box border border-base-content/5 bg-base-100">\n};
    print qq{<table class="table">\n};
    print qq{<thead><tr><th>Date (UTC)</th><th>Action</th><th>Details</th><th>Status</th><th></th></tr></thead>\n};
    print qq{<tbody>\n};

    for my $e (@page_entries) {
        my $esc_date    = Gniza4cpCPanel::UI::esc($e->{date});
        my $esc_action  = Gniza4cpCPanel::UI::esc($e->{action});
        my $esc_details = Gniza4cpCPanel::UI::esc($e->{details});
        my $esc_status  = Gniza4cpCPanel::UI::esc($e->{status});
        my $esc_idx     = Gniza4cpCPanel::UI::esc($e->{idx});

        my $status_badge = $e->{status} eq 'Error' ? 'badge-error' : 'badge-success';
        my $href = 'logs.live.cgi?entry=' . _uri_escape($e->{idx});

        print qq{<tr>\n};
        print qq{  <td class="whitespace-nowrap">$esc_date</td>\n};
        print qq{  <td><span class="badge badge-info badge-sm">$esc_action</span></td>\n};
        print qq{  <td class="text-sm">$esc_details</td>\n};
        print qq{  <td><span class="badge $status_badge badge-sm">$esc_status</span></td>\n};
        print qq{  <td><button type="button" class="btn btn-secondary btn-sm" onclick="location.href='$href'">View</button></td>\n};
        print qq{</tr>\n};
    }

    print qq{</tbody>\n</table>\n</div>\n};

    # Pagination controls
    if ($total_pages > 1) {
        print qq{<div class="flex items-center justify-center gap-2 mt-4">\n};
        if ($page > 1) {
            my $prev = $page - 1;
            print qq{  <button type="button" class="btn btn-sm" onclick="location.href='logs.live.cgi?page=$prev'">&laquo; Prev</button>\n};
        }
        print qq{  <span class="text-sm">Page $page of $total_pages ($total entries)</span>\n};
        if ($page < $total_pages) {
            my $next = $page + 1;
            print qq{  <button type="button" class="btn btn-sm" onclick="location.href='logs.live.cgi?page=$next'">Next &raquo;</button>\n};
        }
        print qq{</div>\n};
    }

    print Gniza4cpCPanel::UI::page_footer();
    print $cpanel->footer();
}

# ── Entry Detail View ────────────────────────────────────────

sub show_entry {
    my ($entry_idx) = @_;

    print "Content-Type: text/html\r\n\r\n";
    print $cpanel->header('');
    print Gniza4cpCPanel::UI::page_header('GNIZA Activity Detail');
    print Gniza4cpCPanel::UI::render_nav('logs.live.cgi');

    # Validate entry index (numeric only)
    unless ($entry_idx =~ /^[0-9]+$/) {
        print qq{<div class="alert alert-error mb-4">Invalid entry.</div>\n};
        print qq{<p><a href="logs.live.cgi" class="link">&larr; Back to activity log</a></p>\n};
        print Gniza4cpCPanel::UI::page_footer();
        print $cpanel->footer();
        return;
    }

    my $content = eval { Cpanel::AdminBin::Call::call('Gniza4cp', 'Restore', 'GET_LOG', $entry_idx) } // '';

    if ($content =~ /^ERROR: (.*)/) {
        print qq{<div class="alert alert-error mb-4">} . Gniza4cpCPanel::UI::esc($1) . qq{</div>\n};
        print qq{<p><a href="logs.live.cgi" class="link">&larr; Back to activity log</a></p>\n};
        print Gniza4cpCPanel::UI::page_footer();
        print $cpanel->footer();
        return;
    }

    # Parse header fields and output from entry content
    my ($date, $action, $details, $status, $output) = ('', '', '', '', '');
    my @lines = split /\n/, $content;
    my @output_lines;
    my $in_output = 0;
    for my $line (@lines) {
        if (!$in_output) {
            if    ($line =~ /^Date:\s+(.+)$/)    { $date    = $1; }
            elsif ($line =~ /^Action:\s+(.+)$/)   { $action  = $1; }
            elsif ($line =~ /^Details:\s+(.+)$/)  { $details = $1; }
            elsif ($line =~ /^Status:\s+(.+)$/)   { $status  = $1; $in_output = 1; }
        } else {
            push @output_lines, $line;
        }
    }

    # Back link
    print qq{<p class="mb-4"><a href="logs.live.cgi" class="link">&larr; Back to activity log</a></p>\n};

    # Entry info card
    my $status_badge = $status eq 'Error' ? 'badge-error' : 'badge-success';
    print qq{<div class="card bg-base-200 shadow-sm border border-base-300 mb-4">\n};
    print qq{<div class="card-body py-3 px-4">\n};
    print qq{<div class="flex flex-wrap gap-4 items-center text-sm">\n};
    print qq{  <span><strong>Date:</strong> } . Gniza4cpCPanel::UI::esc($date) . qq{</span>\n};
    print qq{  <span><strong>Action:</strong> <span class="badge badge-info badge-sm">} . Gniza4cpCPanel::UI::esc($action) . qq{</span></span>\n};
    print qq{  <span><strong>Status:</strong> <span class="badge $status_badge badge-sm">} . Gniza4cpCPanel::UI::esc($status) . qq{</span></span>\n};
    print qq{</div>\n};
    print qq{<div class="text-sm mt-2"><strong>Details:</strong> } . Gniza4cpCPanel::UI::esc($details) . qq{</div>\n};
    print qq{</div>\n</div>\n};

    # Output section
    if (@output_lines) {
        print qq{<h3 class="text-sm font-bold mb-2">Command Output</h3>\n};
        print qq{<pre class="bg-base-100 border border-base-300 rounded-lg p-4 text-sm font-mono overflow-x-auto leading-relaxed">};
        for my $line (@output_lines) {
            my $esc = Gniza4cpCPanel::UI::esc($line);
            if ($line =~ /\[ERROR\]/) {
                print qq{<span class="text-error font-bold">$esc</span>\n};
            } elsif ($line =~ /\[WARN\]/) {
                print qq{<span class="text-warning">$esc</span>\n};
            } elsif ($line =~ /\[DEBUG\]/) {
                print qq{<span class="text-base-content/60">$esc</span>\n};
            } else {
                print "$esc\n";
            }
        }
        print qq{</pre>\n};
    } else {
        print qq{<div class="alert alert-info">No output recorded for this action.</div>\n};
    }

    print Gniza4cpCPanel::UI::page_footer();
    print $cpanel->footer();
}

# ── Helpers ───────────────────────────────────────────────────

sub _uri_escape {
    my $str = shift // '';
    $str =~ s/([^A-Za-z0-9\-._~])/sprintf("%%%02X", ord($1))/ge;
    return $str;
}

1;
