<?php
/**
 * Plugin Name: xpay — Yoast llms.txt Auto-Append
 * Plugin URI:  https://docs.xpay.sh/en/publishers/integrations/yoast-wordpress
 * Description: Automatically appends your xpay agent-payment block to the end of Yoast's auto-generated llms.txt every time it regenerates. Set your block under Settings → xpay llms.txt.
 * Version:     1.0.0
 * Author:      xpay
 * Author URI:  https://xpay.sh
 * License:     MIT
 * Requires at least: 6.0
 * Requires PHP: 7.4
 *
 * How it works:
 *   Yoast SEO regenerates llms.txt as a static file at the WordPress root
 *   whenever you publish, edit, or delete a post. This plugin piggybacks on
 *   the same triggers (save_post, deleted_post) to re-append your xpay block
 *   shortly after Yoast rewrites the file. Idempotent: existing block is
 *   stripped and replaced, never duplicated.
 */

defined('ABSPATH') || exit;

const XPAY_LLMS_OPTION   = 'xpay_llms_block';
const XPAY_LLMS_MARK_OPEN  = '<!-- xpay:block:start -->';
const XPAY_LLMS_MARK_CLOSE = '<!-- xpay:block:end -->';
const XPAY_LLMS_CRON_HOOK = 'xpay_llms_append_run';

/* ────────────────────────────────────────────────────────────────────────
 * Trigger: schedule a delayed append after Yoast regenerates llms.txt.
 * 60s offset gives Yoast plenty of time to finish writing the file.
 * ──────────────────────────────────────────────────────────────────── */
add_action('save_post',     'xpay_llms_schedule', 20);
add_action('deleted_post',  'xpay_llms_schedule', 20);
add_action('trashed_post',  'xpay_llms_schedule', 20);

function xpay_llms_schedule() {
    if (!wp_next_scheduled(XPAY_LLMS_CRON_HOOK)) {
        wp_schedule_single_event(time() + 60, XPAY_LLMS_CRON_HOOK);
    }
}

add_action(XPAY_LLMS_CRON_HOOK, 'xpay_llms_append_block');

/* ────────────────────────────────────────────────────────────────────────
 * Append (or refresh) the xpay block at the end of llms.txt.
 * Idempotent: a previous xpay block (between markers) is removed first.
 * ──────────────────────────────────────────────────────────────────── */
function xpay_llms_append_block() {
    $block = trim((string) get_option(XPAY_LLMS_OPTION, ''));
    if ($block === '') {
        return;
    }

    $path = apply_filters('wpseo_llmstxt_filesystem_path', ABSPATH . 'llms.txt');
    if (!is_string($path) || !file_exists($path) || !is_writable($path)) {
        return;
    }

    $contents = file_get_contents($path);
    if ($contents === false) {
        return;
    }

    // Only operate on Yoast-generated files — refuse to touch hand-rolled ones.
    if (strpos($contents, 'Yoast SEO') === false) {
        return;
    }

    // Strip any prior xpay block (between markers) so we never duplicate.
    $stripped = preg_replace(
        '/\s*' . preg_quote(XPAY_LLMS_MARK_OPEN, '/') . '.*?' . preg_quote(XPAY_LLMS_MARK_CLOSE, '/') . '\s*/s',
        '',
        $contents
    );

    $new = rtrim($stripped) . "\n\n"
         . XPAY_LLMS_MARK_OPEN . "\n"
         . $block . "\n"
         . XPAY_LLMS_MARK_CLOSE . "\n";

    if ($new === $contents) {
        return;
    }

    file_put_contents($path, $new, LOCK_EX);
}

/* ────────────────────────────────────────────────────────────────────────
 * Settings page: Settings → xpay llms.txt
 * ──────────────────────────────────────────────────────────────────── */
add_action('admin_menu', function () {
    add_options_page(
        'xpay llms.txt',
        'xpay llms.txt',
        'manage_options',
        'xpay-llms',
        'xpay_llms_render_settings'
    );
});

add_action('admin_init', function () {
    register_setting('xpay_llms_settings', XPAY_LLMS_OPTION, [
        'type'              => 'string',
        'sanitize_callback' => 'wp_unslash',
        'default'           => '',
    ]);
});

function xpay_llms_render_settings() {
    if (!current_user_can('manage_options')) {
        return;
    }
    $current = (string) get_option(XPAY_LLMS_OPTION, '');
    ?>
    <div class="wrap">
      <h1>xpay llms.txt Auto-Append</h1>
      <p>Paste the xpay agent-payment block from your dashboard
        (<a href="https://app.xpay.sh/dashboard/charge-per-use/account-config" target="_blank">Account Config → Discovery Files</a>).
        It will be appended to the end of Yoast's auto-generated <code>llms.txt</code>
        every time Yoast regenerates the file.</p>
      <form method="post" action="options.php">
        <?php settings_fields('xpay_llms_settings'); ?>
        <textarea name="<?php echo esc_attr(XPAY_LLMS_OPTION); ?>"
          rows="14" cols="90"
          style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace;width:100%;max-width:780px;"
          placeholder="## Agent Payments&#10;...your xpay block from the dashboard..."><?php
            echo esc_textarea($current);
        ?></textarea>
        <p class="description">
          Save this, then publish or update any post. Within ~60 seconds your
          <code>llms.txt</code> will have this block appended at the end —
          existing Yoast content (your articles, hotels, events, etc.) is preserved.
        </p>
        <?php submit_button('Save block'); ?>
      </form>
      <hr>
      <h2>Run now</h2>
      <p>Don't want to wait for the next post update? Click below to run the append immediately.</p>
      <form method="post">
        <?php wp_nonce_field('xpay_llms_run_now', 'xpay_llms_run_nonce'); ?>
        <button type="submit" name="xpay_llms_run_now" class="button button-secondary">Run append now</button>
      </form>
    </div>
    <?php
}

add_action('admin_init', function () {
    if (
        isset($_POST['xpay_llms_run_now']) &&
        check_admin_referer('xpay_llms_run_now', 'xpay_llms_run_nonce') &&
        current_user_can('manage_options')
    ) {
        xpay_llms_append_block();
        add_action('admin_notices', function () {
            echo '<div class="notice notice-success is-dismissible"><p>xpay block appended to llms.txt.</p></div>';
        });
    }
});

/* ────────────────────────────────────────────────────────────────────────
 * Cleanup on deactivation
 * ──────────────────────────────────────────────────────────────────── */
register_deactivation_hook(__FILE__, function () {
    $ts = wp_next_scheduled(XPAY_LLMS_CRON_HOOK);
    if ($ts) {
        wp_unschedule_event($ts, XPAY_LLMS_CRON_HOOK);
    }
});
