<?php

declare(strict_types=1);

require_once dirname(__DIR__, 3) . '/system/bootstrap.php';

$currentUser = myronRequireContentAccess();
$commentService = myronBlogCommentService();
$contentRepository = myronContentRepository();
$csrfToken = myronCsrfToken();
$verifiedNotificationDestinations = myronNotificationEmailsRepository()->listAll(true);

$statusOptions = array_merge(['all'], BlogCommentRepository::STATUSES);
$selectedStatus = strtolower(trim((string) ($_GET['status'] ?? BlogCommentRepository::STATUS_PENDING)));
if (!in_array($selectedStatus, $statusOptions, true)) {
    $selectedStatus = BlogCommentRepository::STATUS_PENDING;
}

$actionStatusMap = [
    'approve-comment' => BlogCommentRepository::STATUS_APPROVED,
    'reject-comment' => BlogCommentRepository::STATUS_REJECTED,
    'mark-spam-comment' => BlogCommentRepository::STATUS_SPAM,
    'delete-comment' => BlogCommentRepository::STATUS_DELETED,
    'restore-comment' => BlogCommentRepository::STATUS_PENDING,
];

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    $currentUser = myronRequireContentAccess(true);
    $commentId = trim((string) ($_POST['comment_id'] ?? ''));
    $action = trim((string) ($_POST['action'] ?? ''));
    $bulkAction = trim((string) ($_POST['bulk_action'] ?? ''));
    $redirectStatus = strtolower(trim((string) ($_POST['status_filter'] ?? $selectedStatus)));
    if (!in_array($redirectStatus, $statusOptions, true)) {
        $redirectStatus = BlogCommentRepository::STATUS_PENDING;
    }

    try {
        myronRequireCsrf($_POST['csrf_token'] ?? null);
        if ($action === 'save-comment-settings') {
            if (!myronUserCanManageContent($currentUser)) {
                throw new RuntimeException('You do not have permission to update comment notification routing.');
            }

            $commentService->updateSettings([
                'notification_email_id' => (string) ($_POST['notification_email_id'] ?? ''),
            ], (string) ($currentUser['id'] ?? ''));
            myronRedirectWithFlash(
                myronBuildAdminUrl('content.comments', ['status' => $redirectStatus]),
                'Comment notification routing updated.',
                'success'
            );
        }

        if ($bulkAction !== '') {
            if (!isset($actionStatusMap[$bulkAction])) {
                throw new RuntimeException('Unknown bulk moderation action.');
            }

            $commentIds = $_POST['comment_ids'] ?? [];
            if (!is_array($commentIds)) {
                $commentIds = [];
            }
            $commentIds = array_values(array_unique(array_filter(array_map(
                static fn (mixed $value): string => trim((string) $value),
                $commentIds
            ))));
            if ($commentIds === []) {
                throw new RuntimeException('Select at least one comment before applying a bulk action.');
            }

            $targetStatus = $actionStatusMap[$bulkAction];
            $updatedCount = 0;
            $skippedCount = 0;
            foreach ($commentIds as $bulkCommentId) {
                try {
                    $commentService->transition($bulkCommentId, $targetStatus, (string) ($currentUser['id'] ?? ''), 'Bulk moderation action.');
                    $updatedCount++;
                } catch (Throwable) {
                    $skippedCount++;
                }
            }

            if ($updatedCount === 0) {
                throw new RuntimeException('No selected comments could be updated for that action.');
            }

            $message = $updatedCount === 1 ? '1 comment updated.' : $updatedCount . ' comments updated.';
            if ($skippedCount > 0) {
                $message .= ' ' . $skippedCount . ' skipped because the requested transition was not available.';
            }
            myronRedirectWithFlash(myronBuildAdminUrl('content.comments', ['status' => $redirectStatus]), $message, 'success');
        }

        if ($commentId === '' || !isset($actionStatusMap[$action])) {
            throw new RuntimeException('Unknown comment moderation action.');
        }
        $targetStatus = $actionStatusMap[$action];
        $reason = trim((string) ($_POST['reason'] ?? ''));
        $commentService->transition($commentId, $targetStatus, (string) ($currentUser['id'] ?? ''), $reason);
        $message = match ($targetStatus) {
            BlogCommentRepository::STATUS_APPROVED => 'Comment approved.',
            BlogCommentRepository::STATUS_REJECTED => 'Comment rejected.',
            BlogCommentRepository::STATUS_SPAM => 'Comment marked as spam.',
            BlogCommentRepository::STATUS_DELETED => 'Comment deleted.',
            default => 'Comment returned to pending review.',
        };
        myronRedirectWithFlash(myronBuildAdminUrl('content.comments', ['status' => $redirectStatus]), $message, 'success');
    } catch (Throwable $exception) {
        myronRedirectWithFlash(
            myronBuildAdminUrl('content.comments', ['status' => $redirectStatus]),
            $exception->getMessage(),
            'error'
        );
    }
}

$canModerateComments = myronUserCanManageContent($currentUser);
$commentSettings = $commentService->settings();
$currentNotificationEmailId = trim((string) ($commentSettings['notification_email_id'] ?? ''));
$verifiedNotificationIds = [];
foreach ($verifiedNotificationDestinations as $destination) {
    $verifiedNotificationIds[(string) ($destination['id'] ?? '')] = true;
}
$currentNotificationUnavailable = $currentNotificationEmailId !== ''
    && !isset($verifiedNotificationIds[$currentNotificationEmailId]);
$statusFilter = $selectedStatus === 'all' ? null : $selectedStatus;
$comments = $commentService->moderationQueue($statusFilter, 100, 0);
$counts = $commentService->countByStatus();
$totalCount = array_sum($counts);
$pagesById = [];
foreach ($contentRepository->listPages() as $page) {
    $pagesById[(string) ($page['id'] ?? '')] = $page;
}

$selectedCommentId = trim((string) ($_GET['comment'] ?? ''));
$selectedComment = $selectedCommentId !== '' ? $commentService->find($selectedCommentId) : null;
$selectedCommentPage = is_array($selectedComment)
    ? ($pagesById[(string) ($selectedComment['page_id'] ?? '')] ?? null)
    : null;

$statusLabels = [
    'all' => 'All',
    BlogCommentRepository::STATUS_PENDING => 'Pending',
    BlogCommentRepository::STATUS_APPROVED => 'Approved',
    BlogCommentRepository::STATUS_REJECTED => 'Rejected',
    BlogCommentRepository::STATUS_SPAM => 'Spam',
    BlogCommentRepository::STATUS_DELETED => 'Deleted',
];
$transitionLabels = [
    BlogCommentRepository::STATUS_PENDING => 'Restore',
    BlogCommentRepository::STATUS_APPROVED => 'Approve',
    BlogCommentRepository::STATUS_REJECTED => 'Reject',
    BlogCommentRepository::STATUS_SPAM => 'Spam',
    BlogCommentRepository::STATUS_DELETED => 'Delete',
];
$transitionActions = [
    BlogCommentRepository::STATUS_PENDING => 'restore-comment',
    BlogCommentRepository::STATUS_APPROVED => 'approve-comment',
    BlogCommentRepository::STATUS_REJECTED => 'reject-comment',
    BlogCommentRepository::STATUS_SPAM => 'mark-spam-comment',
    BlogCommentRepository::STATUS_DELETED => 'delete-comment',
];
$bulkActionLabels = [
    'approve-comment' => 'Approve selected',
    'reject-comment' => 'Reject selected',
    'mark-spam-comment' => 'Mark selected as spam',
    'delete-comment' => 'Delete selected',
];

$excerpt = static function (string $value): string {
    $normalized = trim(preg_replace('/\s+/', ' ', $value) ?? '');
    if (strlen($normalized) <= 180) {
        return $normalized;
    }
    return substr($normalized, 0, 177) . '...';
};

$commentDetailUrl = static function (string $commentId) use ($selectedStatus): string {
    return myronBuildAdminUrl('content.comments', [
        'status' => $selectedStatus,
        'comment' => $commentId,
    ]);
};

myronRenderAdminShellStart($currentUser, [
    'title' => 'Comments',
    'titleContext' => 'Content',
    'activeItem' => 'content-comments',
]);
?>
<div class="mc-workspace__header">
  <?php myronRenderAdminBreadcrumbs([
      ['label' => 'Content', 'href' => myronBuildAdminUrl('content.pages')],
      ['label' => 'Content Studio', 'href' => myronBuildAdminUrl('content.pages')],
      ['label' => 'Comments'],
  ]); ?>
  <div class="mc-workspace__title-row mc-workspace__title-row--actions">
    <h1 class="mc-workspace__title">Comments</h1>
    <div class="mc-workspace__actions">
      <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('content.pages')) ?>">Back to Pages</a>
    </div>
  </div>
  <p class="mc-workspace__subtitle">Review public blog comments before they appear on published posts.</p>
</div>

<div class="mc-page-canvas mc-page-canvas--site">
  <div class="sg-main">
    <section class="sg-section" aria-label="Comment moderation status filters">
      <div class="sg-card__actions">
        <?php foreach ($statusLabels as $status => $label): ?>
        <?php
          $count = $status === 'all' ? $totalCount : (int) ($counts[$status] ?? 0);
          $className = 'sg-pill' . ($selectedStatus === $status ? ' sg-pill--active' : '');
        ?>
        <a class="<?= myronEscape($className) ?>" href="<?= myronEscape(myronBuildAdminUrl('content.comments', ['status' => $status])) ?>">
          <?= myronEscape($label) ?> <code><?= myronEscape((string) $count) ?></code>
        </a>
        <?php endforeach; ?>
      </div>
    </section>

    <section class="sg-section">
      <?php if ($canModerateComments): ?>
      <form method="post" class="mc-comments-bulk-actions" id="comments-bulk-form">
        <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
        <input type="hidden" name="status_filter" value="<?= myronEscape($selectedStatus) ?>">
        <label class="sg-field">
          <span class="sg-field__label">Bulk action</span>
          <select class="sg-field__control" name="bulk_action" required>
            <option value="">Choose action</option>
            <?php foreach ($bulkActionLabels as $bulkAction => $bulkLabel): ?>
            <option value="<?= myronEscape($bulkAction) ?>"><?= myronEscape($bulkLabel) ?></option>
            <?php endforeach; ?>
          </select>
        </label>
        <button class="sg-button sg-button--secondary" type="submit">Apply</button>
      </form>
      <?php endif; ?>
      <div class="mc-page-grid mc-page-grid--comments" role="table" aria-label="Comment moderation queue" data-mc-sortable-grid>
        <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
          <span role="columnheader" aria-label="Select comments">
            <input type="checkbox" aria-label="Select all visible comments" data-mc-comments-select-all>
          </span>
          <span role="columnheader" data-mc-sort-key="comment"><button class="mc-page-grid__sort" type="button">Comment</button></span>
          <span role="columnheader" data-mc-sort-key="page"><button class="mc-page-grid__sort" type="button">Page</button></span>
          <span role="columnheader" data-mc-sort-key="submitted"><button class="mc-page-grid__sort" type="button">Submitted</button></span>
          <span role="columnheader" data-mc-sort-key="status"><button class="mc-page-grid__sort" type="button">Status</button></span>
          <span role="columnheader">Actions</span>
        </div>

        <?php if ($comments === []): ?>
        <div class="mc-page-grid__row" role="row">
          <span class="mc-page-grid__cell" role="cell">-</span>
          <span class="mc-page-grid__cell" role="cell">No comments match this filter.</span>
          <span class="mc-page-grid__cell" role="cell">-</span>
          <span class="mc-page-grid__cell" role="cell">-</span>
          <span class="mc-page-grid__cell" role="cell">-</span>
          <span class="mc-page-grid__cell" role="cell">-</span>
        </div>
        <?php endif; ?>

        <?php foreach ($comments as $comment): ?>
        <?php
          $commentStatus = (string) ($comment['status'] ?? BlogCommentRepository::STATUS_PENDING);
          $page = $pagesById[(string) ($comment['page_id'] ?? '')] ?? null;
          $pageTitle = is_array($page) ? (string) ($page['title'] ?? 'Unknown page') : 'Unknown page';
          $pagePath = is_array($page) ? (string) ($page['path'] ?? '') : '';
          $pageUrl = $pagePath !== '' ? myronBuildPublicPageUrl($pagePath) : '';
          $availableTransitions = $commentService->availableTransitionsForStatus($commentStatus);
        ?>
        <div
          class="mc-page-grid__row"
          role="row"
          data-mc-filter-row
          data-sort-comment="<?= myronEscape((string) ($comment['author_name'] ?? '')) ?>"
          data-sort-page="<?= myronEscape($pageTitle) ?>"
          data-sort-submitted="<?= myronEscape((string) ($comment['submitted_at'] ?? '')) ?>"
          data-sort-status="<?= myronEscape($commentStatus) ?>"
        >
          <span class="mc-page-grid__cell mc-page-grid__cell--select" role="cell">
            <?php if ($canModerateComments && $availableTransitions !== []): ?>
            <input
              type="checkbox"
              name="comment_ids[]"
              value="<?= myronEscape((string) $comment['id']) ?>"
              form="comments-bulk-form"
              aria-label="Select comment by <?= myronEscape((string) ($comment['author_name'] ?? 'reader')) ?>"
              data-mc-comments-select
            >
            <?php endif; ?>
          </span>
          <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell">
            <a class="mc-page-grid__name" href="<?= myronEscape($commentDetailUrl((string) $comment['id'])) ?>" data-mc-sidesheet-open="comment-detail-sheet"><?= myronEscape((string) ($comment['author_name'] ?? '')) ?></a>
            <span class="mc-page-grid__subtle"><?= myronEscape((string) ($comment['author_email'] ?? '')) ?></span>
            <span class="mc-page-grid__subtle"><?= myronEscape($excerpt((string) ($comment['body'] ?? ''))) ?></span>
          </span>
          <span class="mc-page-grid__cell" role="cell">
            <?php if ($pageUrl !== ''): ?>
            <a class="mc-page-grid__name" href="<?= myronEscape($pageUrl) ?>" target="_blank" rel="noreferrer"><?= myronEscape($pageTitle) ?></a>
            <?php else: ?>
            <span class="mc-page-grid__name"><?= myronEscape($pageTitle) ?></span>
            <?php endif; ?>
            <?php if ($pagePath !== ''): ?><code><?= myronEscape($pagePath) ?></code><?php endif; ?>
          </span>
          <span class="mc-page-grid__cell" role="cell"><?= myronEscape((string) ($comment['submitted_at'] ?? '')) ?></span>
          <span class="mc-page-grid__cell" role="cell">
            <span class="sg-pill <?= $commentStatus === BlogCommentRepository::STATUS_APPROVED ? 'sg-pill--active' : '' ?>"><?= myronEscape($statusLabels[$commentStatus] ?? $commentStatus) ?></span>
          </span>
          <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell">
            <?php if ($canModerateComments && $availableTransitions !== []): ?>
            <?php foreach ($availableTransitions as $transitionStatus): ?>
            <form method="post" class="mc-page-grid__action-form">
              <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
              <input type="hidden" name="comment_id" value="<?= myronEscape((string) $comment['id']) ?>">
              <input type="hidden" name="status_filter" value="<?= myronEscape($selectedStatus) ?>">
              <input type="hidden" name="reason" value="">
              <button
                class="sg-button <?= $transitionStatus === BlogCommentRepository::STATUS_APPROVED ? 'sg-button--primary' : 'sg-button--secondary' ?>"
                type="submit"
                name="action"
                value="<?= myronEscape($transitionActions[$transitionStatus]) ?>"
              ><?= myronEscape($transitionLabels[$transitionStatus]) ?></button>
            </form>
            <?php endforeach; ?>
            <?php else: ?>
            <span class="mc-page-grid__muted">No actions</span>
            <?php endif; ?>
          </span>
        </div>
        <?php endforeach; ?>
      </div>
    </section>

    <?php if ($canModerateComments): ?>
    <section class="sg-section" aria-label="Comment notification routing">
      <div class="sg-section__header">
        <div>
          <h2 class="sg-section__title">Notification Routing</h2>
          <p class="sg-section__description">Choose the verified destination that receives new pending-comment moderation notices.</p>
        </div>
      </div>
      <form method="post" class="sg-form-grid">
        <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
        <input type="hidden" name="status_filter" value="<?= myronEscape($selectedStatus) ?>">
        <input type="hidden" name="action" value="save-comment-settings">
        <label class="sg-field sg-field--span-2">
          <span class="sg-field__label">Verified Destination</span>
          <select class="sg-field__control" name="notification_email_id">
            <option value="">Do not send comment notifications</option>
            <?php foreach ($verifiedNotificationDestinations as $destination): ?>
            <?php
              $destinationId = (string) ($destination['id'] ?? '');
              $destinationLabel = trim((string) ($destination['label'] ?? '')) ?: (string) ($destination['address'] ?? '');
              $destinationAddress = (string) ($destination['address'] ?? '');
            ?>
            <option value="<?= myronEscape($destinationId) ?>"<?= $currentNotificationEmailId === $destinationId ? ' selected' : '' ?>>
              <?= myronEscape($destinationLabel . ' <' . $destinationAddress . '>') ?>
            </option>
            <?php endforeach; ?>
          </select>
          <span class="sg-field__hint">Only verified destinations can be selected. Comment capture continues even if mail delivery fails.</span>
        </label>
        <div class="sg-form-grid__actions">
          <button class="sg-button sg-button--secondary" type="submit">Save Routing</button>
          <a class="sg-button sg-button--ghost" href="<?= myronEscape(myronBuildAdminUrl('administration.notificationEmails')) ?>">Manage Destinations</a>
        </div>
      </form>
      <?php if ($verifiedNotificationDestinations === []): ?>
      <p class="sg-status sg-status--warning">No verified destinations are available yet. Add and verify one before routing comment notifications to a specific address.</p>
      <?php elseif ($currentNotificationUnavailable): ?>
      <p class="sg-status sg-status--warning">The previously selected destination is no longer verified. Choose another verified destination or leave notifications disabled.</p>
      <?php endif; ?>
    </section>
    <?php endif; ?>

    <?php if (is_array($selectedComment)): ?>
    <?php
      $detailStatus = (string) ($selectedComment['status'] ?? BlogCommentRepository::STATUS_PENDING);
      $detailPageTitle = is_array($selectedCommentPage) ? (string) ($selectedCommentPage['title'] ?? 'Unknown page') : 'Unknown page';
      $detailPagePath = is_array($selectedCommentPage) ? (string) ($selectedCommentPage['path'] ?? '') : '';
      $detailTransitions = $commentService->availableTransitionsForStatus($detailStatus);
      ob_start();
    ?>
    <div class="mc-comment-detail">
      <dl class="mc-comment-detail__meta">
        <div>
          <dt>Author</dt>
          <dd><?= myronEscape((string) ($selectedComment['author_name'] ?? '')) ?></dd>
        </div>
        <div>
          <dt>Email</dt>
          <dd><?= myronEscape((string) ($selectedComment['author_email'] ?? '')) ?></dd>
        </div>
        <div>
          <dt>Page</dt>
          <dd>
            <?= myronEscape($detailPageTitle) ?>
            <?php if ($detailPagePath !== ''): ?><br><code><?= myronEscape($detailPagePath) ?></code><?php endif; ?>
          </dd>
        </div>
        <div>
          <dt>Submitted</dt>
          <dd><?= myronEscape((string) ($selectedComment['submitted_at'] ?? '')) ?></dd>
        </div>
        <div>
          <dt>Status</dt>
          <dd><span class="sg-pill <?= $detailStatus === BlogCommentRepository::STATUS_APPROVED ? 'sg-pill--active' : '' ?>"><?= myronEscape($statusLabels[$detailStatus] ?? $detailStatus) ?></span></dd>
        </div>
      </dl>
      <section class="mc-comment-detail__body" aria-label="Comment body">
        <?= nl2br(myronEscape((string) ($selectedComment['body'] ?? ''))) ?>
      </section>
      <?php if ($canModerateComments && $detailTransitions !== []): ?>
      <div class="mc-side-sheet__actions">
        <?php foreach ($detailTransitions as $transitionStatus): ?>
        <form method="post" class="mc-page-grid__action-form">
          <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
          <input type="hidden" name="comment_id" value="<?= myronEscape((string) $selectedComment['id']) ?>">
          <input type="hidden" name="status_filter" value="<?= myronEscape($selectedStatus) ?>">
          <input type="hidden" name="reason" value="">
          <button
            class="sg-button <?= $transitionStatus === BlogCommentRepository::STATUS_APPROVED ? 'sg-button--primary' : 'sg-button--secondary' ?>"
            type="submit"
            name="action"
            value="<?= myronEscape($transitionActions[$transitionStatus]) ?>"
          ><?= myronEscape($transitionLabels[$transitionStatus]) ?></button>
        </form>
        <?php endforeach; ?>
      </div>
      <?php else: ?>
      <p class="mc-page-grid__muted">No moderation actions are available for this comment.</p>
      <?php endif; ?>
    </div>
    <?php $commentDetailBody = (string) ob_get_clean(); ?>
    <?php myronRenderAdminSidesheet('comment-detail-sheet', 'Review Comment', $commentDetailBody, [
        'description' => 'Inspect the full comment before moderation.',
        'size' => 'lg',
    ]); ?>
    <button type="button" hidden data-mc-sidesheet-open="comment-detail-sheet" data-comment-detail-autopen>Open comment detail</button>
    <script>document.addEventListener('DOMContentLoaded', function () { var trigger = document.querySelector('[data-comment-detail-autopen]'); if (trigger) { trigger.click(); } });</script>
    <?php endif; ?>
  </div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  var selectAll = document.querySelector('[data-mc-comments-select-all]');
  if (!selectAll) {
    return;
  }
  var boxes = Array.prototype.slice.call(document.querySelectorAll('[data-mc-comments-select]'));
  selectAll.addEventListener('change', function () {
    boxes.forEach(function (box) {
      box.checked = selectAll.checked;
    });
  });
  boxes.forEach(function (box) {
    box.addEventListener('change', function () {
      var checkedCount = boxes.filter(function (item) { return item.checked; }).length;
      selectAll.checked = checkedCount === boxes.length && boxes.length > 0;
      selectAll.indeterminate = checkedCount > 0 && checkedCount < boxes.length;
    });
  });
});
</script>
<?php myronRenderAdminShellEnd(); ?>
