<?php
require_once __DIR__ . '/mj_v304_bootstrap.php';

function mjv304_item_table(string $itemType): string {
    $map = ['listing'=>'listings','company'=>'companies','deal'=>'deals'];
    $itemType = strtolower(trim($itemType));
    if (!isset($map[$itemType])) { throw new InvalidArgumentException('Invalid review item type.'); }
    return $map[$itemType];
}

function mjv304_detect_pk(string $table): string {
    $row = mjv304_fetch_one("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? AND CONSTRAINT_NAME='PRIMARY' ORDER BY ORDINAL_POSITION LIMIT 1", [$table]);
    return $row['COLUMN_NAME'] ?? 'id';
}

function mjv304_fetch_item(string $itemType, int $itemId): array {
    $table = mjv304_item_table($itemType);
    if (!mjv304_table_exists($table)) { throw new RuntimeException('Table not found: '.$table); }
    $pk = mjv304_detect_pk($table);
    $row = mjv304_fetch_one("SELECT * FROM `$table` WHERE `$pk`=? LIMIT 1", [$itemId]);
    if (!$row) { throw new RuntimeException('Item not found.'); }
    return $row;
}

function mjv304_submit_active_edit_review(string $itemType, int $itemId, int $userId, array $newData): int {
    $itemType = strtolower(trim($itemType));
    $oldData = mjv304_fetch_item($itemType, $itemId);
    unset($newData['id'], $newData['created_at'], $newData['updated_at'], $newData['approved_at'], $newData['status']);

    mjv304_execute("INSERT INTO mj_admin_review_queue (item_type,item_id,user_id,status,old_data_json,new_data_json,submitted_at) VALUES (?,?,?,'pending',?,?,NOW())", [
        $itemType, $itemId, $userId, mjv304_json($oldData), mjv304_json($newData)
    ]);
    $reviewId = (int)mjv304_db()->lastInsertId();
    mjv304_admin_notify('Edit review pending', ucfirst($itemType).' #'.$itemId.' has new changes waiting for approval.', 'review', 'admin/review-queue.php?review_id='.$reviewId, ['review_id'=>$reviewId,'item_type'=>$itemType,'item_id'=>$itemId]);
    mjv304_notify('user', $userId, 'Changes submitted for review', 'Your '.$itemType.' update is pending admin approval. Old live version remains active.', 'review', 'my-reviews.php?review_id='.$reviewId, ['review_id'=>$reviewId]);
    return $reviewId;
}

function mjv304_apply_review(int $reviewId, int $adminId): void {
    $review = mjv304_fetch_one("SELECT * FROM mj_admin_review_queue WHERE id=?", [$reviewId]);
    if (!$review) { throw new RuntimeException('Review not found.'); }
    if ($review['status'] !== 'pending') { throw new RuntimeException('Review already processed.'); }
    $table = mjv304_item_table($review['item_type']);
    $pk = mjv304_detect_pk($table);
    $columns = mjv304_table_columns($table);
    $newData = mjv304_decode_json($review['new_data_json']);
    $sets = []; $params = [];
    foreach ($newData as $column => $value) {
        if (in_array($column, $columns, true) && $column !== $pk) {
            $sets[] = "`$column`=?"; $params[] = $value;
        }
    }
    if (in_array('updated_at', $columns, true)) { $sets[] = "`updated_at`=NOW()"; }
    if (in_array('review_status', $columns, true)) { $sets[] = "`review_status`='approved'"; }
    if (!$sets) { throw new RuntimeException('No safe columns found to update.'); }
    $params[] = (int)$review['item_id'];
    mjv304_execute("UPDATE `$table` SET ".implode(',', $sets)." WHERE `$pk`=?", $params);
    mjv304_execute("UPDATE mj_admin_review_queue SET status='approved', reviewed_by=?, reviewed_at=NOW(), updated_at=NOW() WHERE id=?", [$adminId, $reviewId]);
    mjv304_notify('user', (int)$review['user_id'], ucfirst($review['item_type']).' changes approved', 'Your changes are now live.', 'review', null, ['review_id'=>$reviewId]);
}

function mjv304_reject_review(int $reviewId, int $adminId, string $reason): void {
    $review = mjv304_fetch_one("SELECT * FROM mj_admin_review_queue WHERE id=?", [$reviewId]);
    if (!$review) { throw new RuntimeException('Review not found.'); }
    if ($review['status'] !== 'pending') { throw new RuntimeException('Review already processed.'); }
    mjv304_execute("UPDATE mj_admin_review_queue SET status='rejected', reject_reason=?, reviewed_by=?, reviewed_at=NOW(), updated_at=NOW() WHERE id=?", [$reason, $adminId, $reviewId]);
    mjv304_notify('user', (int)$review['user_id'], ucfirst($review['item_type']).' changes rejected', $reason ?: 'Admin rejected your submitted changes.', 'review', null, ['review_id'=>$reviewId]);
}

function mjv304_diff_rows(array $old, array $new): array {
    $keys = array_unique(array_merge(array_keys($old), array_keys($new)));
    $out = [];
    foreach ($keys as $key) {
        $ov = $old[$key] ?? '';
        $nv = $new[$key] ?? '';
        if ((string)$ov !== (string)$nv) { $out[] = ['field'=>$key, 'old'=>$ov, 'new'=>$nv]; }
    }
    return $out;
}
