<?php
/**
 * Content Events Observer
 *
 * Monitors posts, comments, media, and taxonomy terms.
 * Only registered in "all" logging mode (too noisy for other modes).
 *
 * 17 event types across 14 hooks.
 *
 * @package VMPFence
 * @since 2.2.5
 */

if (!defined('ABSPATH')) {
    exit;
}

class VMPFence_Audit_Log_Observer_Content extends VMPFence_Audit_Log_Observer {

    /**
     * Register all content-related WordPress hooks.
     *
     * @return void
     */
    public function register_hooks() {
        // Posts
        add_action('transition_post_status', array($this, 'on_post_status_change'), 10, 3);
        add_action('save_post',              array($this, 'on_post_saved'), 10, 3);
        add_action('before_delete_post',     array($this, 'on_post_deleted'));
        add_action('trashed_post',           array($this, 'on_post_trashed'));
        add_action('untrashed_post',         array($this, 'on_post_restored'));

        // Comments
        add_action('wp_insert_comment',        array($this, 'on_comment_added'), 10, 2);
        add_action('transition_comment_status', array($this, 'on_comment_status_change'), 10, 3);
        add_action('delete_comment',            array($this, 'on_comment_deleted'));

        // Media
        add_action('add_attachment',    array($this, 'on_media_uploaded'));
        add_action('edit_attachment',   array($this, 'on_media_edited'));
        add_action('delete_attachment', array($this, 'on_media_deleted'));

        // Terms (taxonomies)
        add_action('created_term', array($this, 'on_term_created'), 10, 3);
        add_action('edited_term',  array($this, 'on_term_edited'), 10, 3);
        add_action('delete_term',  array($this, 'on_term_deleted'), 10, 5);
    }

    // =========================================================================
    // POST CALLBACKS
    // =========================================================================

    /**
     * Post status transition — detects publish and draft creation.
     *
     * @param string   $new_status
     * @param string   $old_status
     * @param \WP_Post $post
     */
    public function on_post_status_change($new_status, $old_status, $post) {
        // Skip auto-saves, revisions, nav menu items
        if (wp_is_post_autosave($post) || wp_is_post_revision($post)) {
            return;
        }
        if ($post->post_type === 'nav_menu_item') {
            return;
        }

        // Published
        if ($new_status === 'publish' && $old_status !== 'publish') {
            $this->log('post_published', array(
                'post_id'    => $post->ID,
                'post_title' => $post->post_title,
                'post_type'  => $post->post_type,
                'old_status' => $old_status,
            ), 'info');
            return;
        }

        // Draft created
        if ($new_status === 'draft' && $old_status === 'auto-draft') {
            $this->log('post_draft_created', array(
                'post_id'    => $post->ID,
                'post_title' => $post->post_title,
                'post_type'  => $post->post_type,
            ), 'info');
            return;
        }
    }

    /**
     * Post saved — detect updates (not creates).
     *
     * @param int      $post_id
     * @param \WP_Post $post
     * @param bool     $update
     */
    public function on_post_saved($post_id, $post, $update) {
        // Only track updates, not creates
        if (!$update) {
            return;
        }
        // Skip auto-saves, revisions, nav menu items
        if (wp_is_post_autosave($post) || wp_is_post_revision($post)) {
            return;
        }
        if ($post->post_type === 'nav_menu_item') {
            return;
        }

        $this->log('post_updated', array(
            'post_id'    => $post_id,
            'post_title' => $post->post_title,
            'post_type'  => $post->post_type,
            'status'     => $post->post_status,
        ), 'info');
    }

    /**
     * Post permanently deleted.
     *
     * @param int $post_id
     */
    public function on_post_deleted($post_id) {
        $post = get_post($post_id);
        if (!$post || $post->post_type === 'nav_menu_item') {
            return;
        }
        if (wp_is_post_revision($post)) {
            return;
        }

        $this->log('post_deleted', array(
            'post_id'    => $post_id,
            'post_title' => $post->post_title,
            'post_type'  => $post->post_type,
        ), 'warning');
    }

    /**
     * Post moved to trash.
     *
     * @param int $post_id
     */
    public function on_post_trashed($post_id) {
        $post = get_post($post_id);
        $this->log('post_trashed', array(
            'post_id'    => $post_id,
            'post_title' => $post ? $post->post_title : '',
            'post_type'  => $post ? $post->post_type : '',
        ), 'info');
    }

    /**
     * Post restored from trash.
     *
     * @param int $post_id
     */
    public function on_post_restored($post_id) {
        $post = get_post($post_id);
        $this->log('post_restored', array(
            'post_id'    => $post_id,
            'post_title' => $post ? $post->post_title : '',
            'post_type'  => $post ? $post->post_type : '',
        ), 'info');
    }

    // =========================================================================
    // COMMENT CALLBACKS
    // =========================================================================

    /**
     * New comment inserted.
     *
     * @param int         $comment_id
     * @param \WP_Comment $comment
     */
    public function on_comment_added($comment_id, $comment) {
        $this->log('comment_posted', array(
            'comment_id' => $comment_id,
            'post_id'    => $comment->comment_post_ID,
            'author'     => $comment->comment_author,
            'email'      => $comment->comment_author_email,
            'status'     => $comment->comment_approved,
        ), 'info');
    }

    /**
     * Comment status changed.
     *
     * @param string      $new_status
     * @param string      $old_status
     * @param \WP_Comment $comment
     */
    public function on_comment_status_change($new_status, $old_status, $comment) {
        $event_map = array(
            'approved' => 'comment_approved',
            'spam'     => 'comment_spam',
            'trash'    => 'comment_trashed',
        );

        $event_type = isset($event_map[$new_status]) ? $event_map[$new_status] : null;
        if (!$event_type) {
            return;
        }

        $this->log($event_type, array(
            'comment_id' => $comment->comment_ID,
            'post_id'    => $comment->comment_post_ID,
            'old_status' => $old_status,
            'new_status' => $new_status,
        ), 'info');
    }

    /**
     * Comment permanently deleted.
     *
     * @param int $comment_id
     */
    public function on_comment_deleted($comment_id) {
        $comment = get_comment($comment_id);
        $this->log('comment_deleted', array(
            'comment_id' => $comment_id,
            'post_id'    => $comment ? $comment->comment_post_ID : 0,
        ), 'info');
    }

    // =========================================================================
    // MEDIA CALLBACKS
    // =========================================================================

    /**
     * Media file uploaded.
     *
     * @param int $attachment_id
     */
    public function on_media_uploaded($attachment_id) {
        $attachment = get_post($attachment_id);
        $this->log('media_uploaded', array(
            'attachment_id' => $attachment_id,
            'filename'      => $attachment ? basename(get_attached_file($attachment_id)) : '',
            'mime_type'     => $attachment ? $attachment->post_mime_type : '',
        ), 'info');
    }

    /**
     * Media file edited.
     *
     * @param int $attachment_id
     */
    public function on_media_edited($attachment_id) {
        $attachment = get_post($attachment_id);
        $this->log('media_edited', array(
            'attachment_id' => $attachment_id,
            'filename'      => $attachment ? basename(get_attached_file($attachment_id)) : '',
        ), 'info');
    }

    /**
     * Media file deleted.
     *
     * @param int $attachment_id
     */
    public function on_media_deleted($attachment_id) {
        $attachment = get_post($attachment_id);
        $this->log('media_deleted', array(
            'attachment_id' => $attachment_id,
            'filename'      => $attachment ? basename(get_attached_file($attachment_id)) : '',
        ), 'info');
    }

    // =========================================================================
    // TERM CALLBACKS
    // =========================================================================

    /**
     * Taxonomy term created.
     *
     * @param int    $term_id
     * @param int    $tt_id
     * @param string $taxonomy
     */
    public function on_term_created($term_id, $tt_id, $taxonomy) {
        $term = get_term($term_id, $taxonomy);
        $this->log('term_created', array(
            'term_id'  => $term_id,
            'name'     => $term && !is_wp_error($term) ? $term->name : '',
            'taxonomy' => $taxonomy,
        ), 'info');
    }

    /**
     * Taxonomy term edited.
     *
     * @param int    $term_id
     * @param int    $tt_id
     * @param string $taxonomy
     */
    public function on_term_edited($term_id, $tt_id, $taxonomy) {
        $term = get_term($term_id, $taxonomy);
        $this->log('term_edited', array(
            'term_id'  => $term_id,
            'name'     => $term && !is_wp_error($term) ? $term->name : '',
            'taxonomy' => $taxonomy,
        ), 'info');
    }

    /**
     * Taxonomy term deleted.
     *
     * @param int    $term_id
     * @param int    $tt_id
     * @param string $taxonomy
     * @param mixed  $deleted_term
     * @param array  $object_ids
     */
    public function on_term_deleted($term_id, $tt_id, $taxonomy, $deleted_term, $object_ids) {
        $this->log('term_deleted', array(
            'term_id'  => $term_id,
            'name'     => is_object($deleted_term) ? $deleted_term->name : '',
            'taxonomy' => $taxonomy,
        ), 'info');
    }
}
