<?php
/**
 * Margin change history — append-only log of per-product margin transitions
 * used by the "Revert" UI on the Products page.
 *
 * Rows are inserted by a WordPress action handler bound to
 * skyemag_margin_changed (see Plugin::register_services). The class only
 * deals with persistence and simple retrieval/cleanup queries; the admin
 * glue lives in ProductsPage and the UI in admin.js.
 *
 * @package SkyEmagSync
 */

namespace SkyEmagSync\History;

defined( 'ABSPATH' ) || exit;

class MarginHistory {

    /**
     * Action handler for skyemag_margin_changed. Inserts one row.
     */
    public static function record( int $post_id, ?float $old, ?float $new ): void {
        if ( $post_id <= 0 ) {
            return;
        }
        if ( $old === $new ) {
            return; // defensive — the hook already guards, but cheap double check
        }

        global $wpdb;
        $wpdb->insert(
            $wpdb->prefix . 'skyemag_margin_history',
            [
                'product_id' => $post_id,
                'old_margin' => $old,
                'new_margin' => $new,
                'user_id'    => get_current_user_id() ?: null,
                'changed_at' => current_time( 'mysql' ),
            ],
            [ '%d', '%f', '%f', '%d', '%s' ]
        );
    }

    /**
     * Fetch the most recent transitions for a product, newest first.
     *
     * @return array<int,array{id:int,old_margin:?float,new_margin:?float,user_id:?int,changed_at:string,user_name:string}>
     */
    public static function get_for_product( int $post_id, int $limit = 20 ): array {
        global $wpdb;
        $table = $wpdb->prefix . 'skyemag_margin_history';

        $rows = $wpdb->get_results( $wpdb->prepare(
            "SELECT id, product_id, old_margin, new_margin, user_id, changed_at
             FROM {$table}
             WHERE product_id = %d
             ORDER BY id DESC
             LIMIT %d",
            $post_id,
            max( 1, min( 100, $limit ) )
        ), ARRAY_A ) ?: [];

        $out = [];
        foreach ( $rows as $r ) {
            $user_name = '';
            if ( ! empty( $r['user_id'] ) ) {
                $user = get_userdata( (int) $r['user_id'] );
                if ( $user ) {
                    $user_name = $user->display_name ?: $user->user_login;
                }
            }
            $out[] = [
                'id'         => (int) $r['id'],
                'old_margin' => null !== $r['old_margin'] ? (float) $r['old_margin'] : null,
                'new_margin' => null !== $r['new_margin'] ? (float) $r['new_margin'] : null,
                'user_id'    => (int) $r['user_id'],
                'user_name'  => $user_name,
                'changed_at' => (string) $r['changed_at'],
            ];
        }
        return $out;
    }

    /**
     * Total transitions recorded for a product.
     */
    public static function count_for_product( int $post_id ): int {
        global $wpdb;
        $table = $wpdb->prefix . 'skyemag_margin_history';
        return (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$table} WHERE product_id = %d",
            $post_id
        ) );
    }

    /**
     * Look up a single row by id, scoped to a product so URLs from one
     * page can't revert across products.
     *
     * @return array{id:int,product_id:int,old_margin:?float,new_margin:?float}|null
     */
    public static function get_entry( int $entry_id, int $post_id ): ?array {
        global $wpdb;
        $table = $wpdb->prefix . 'skyemag_margin_history';

        $row = $wpdb->get_row( $wpdb->prepare(
            "SELECT id, product_id, old_margin, new_margin
             FROM {$table}
             WHERE id = %d AND product_id = %d",
            $entry_id,
            $post_id
        ), ARRAY_A );

        if ( ! $row ) {
            return null;
        }
        return [
            'id'         => (int) $row['id'],
            'product_id' => (int) $row['product_id'],
            'old_margin' => null !== $row['old_margin'] ? (float) $row['old_margin'] : null,
            'new_margin' => null !== $row['new_margin'] ? (float) $row['new_margin'] : null,
        ];
    }

    /**
     * Bulk prune entries older than $days. 0 or negative disables pruning.
     * Returns number of rows removed.
     */
    public static function prune_older_than( int $days ): int {
        if ( $days <= 0 ) {
            return 0;
        }
        global $wpdb;
        $table = $wpdb->prefix . 'skyemag_margin_history';
        return (int) $wpdb->query( $wpdb->prepare(
            "DELETE FROM {$table} WHERE changed_at < DATE_SUB(NOW(), INTERVAL %d DAY)",
            $days
        ) );
    }

    /**
     * Remove all history for a product (used when a product is permanently deleted).
     */
    public static function clear_for_product( int $post_id ): int {
        global $wpdb;
        $table = $wpdb->prefix . 'skyemag_margin_history';
        return (int) $wpdb->delete( $table, [ 'product_id' => $post_id ], [ '%d' ] );
    }
}
