class Admin::ChangesController

def admin_page_url(page)

def admin_page_url(page)
  "/admin/pages/#{page.id}"
end

def build_change_entry(version)

def build_change_entry(version)
  page = Page.find_by(id: version.item_id)
  return {} unless page
  {
    action: version.event.titleize,
    diff: build_diff(version),
    id: version.id,
    page_title: page.title,
    page_url: admin_page_url(page),
    updated_at: format_timestamp(version.created_at),
    user_name: user_name(version.whodunnit),
  }
end

def build_diff(version)

def build_diff(version)
  related_versions = PaperTrail::Version.where(transaction_id: version.transaction_id)
  diffs = related_versions.flat_map { |v| diff_fields(v) }.compact
  diffs.any? ? diffs.join('<br />') : nil
end

def diff_fields(version)

def diff_fields(version)
  version.changeset.map do |field, (old_val, new_val)|
    next unless renderable_diff?(field, old_val, new_val)
    render_field_diff(version, field, old_val, new_val)
  end
end

def fetch_recent_page_versions

def fetch_recent_page_versions
  PaperTrail::Version.
    where(item_type: 'Page').
    joins('INNER JOIN pages ON pages.id = versions.item_id').
    where(pages: { site_id: current_site.id }).
    where('versions.created_at >= ?', 1.month.ago).
    order(created_at: :desc).
    limit(25)
end

def format_timestamp(timestamp)

def format_timestamp(timestamp)
  timestamp.strftime('%A, %B %d, %I:%M %p')
end

def ignored_fields

def ignored_fields
  %w[
    created_at
    created_by_id
    id
    lock_version
    name
    page_id
    published_at
    updated_at
    updated_by_id
  ].freeze
end

def initialize_variables

def initialize_variables
  @user = current_user
  @controller_name = 'changes'
  @template_name = 'show'
end

def label_for_version(version)

def label_for_version(version)
  case version.item_type
  when 'PagePart' then PagePart.find_by(id: version.item_id)&.name || 'Unknown PagePart'
  when 'PageField' then PageField.find_by(id: version.item_id)&.name || 'Unknown PageField'
  else version.item_type
  end
end

def load_changes

def load_changes
  return load_single_change if params[:version_id].present?
  load_recent_changes
end

def load_recent_changes

def load_recent_changes
  fetch_recent_page_versions.map { |version| build_change_entry(version) }
end

def load_single_change

def load_single_change
  version = PaperTrail::Version.find_by(id: params[:version_id])
  version ? [build_change_entry(version)] : []
end

def render_field_diff(version, field, old_val, new_val)

def render_field_diff(version, field, old_val, new_val)
  diff_html = Diffy::Diff.new(old_val, new_val, context: 1).to_s(:html)
  label = version.item_type == 'Page' ? field : label_for_version(version)
  "<h2>#{label.humanize.titleize}</h2>#{diff_html}"
end

def renderable_diff?(field, old_val, new_val)

def renderable_diff?(field, old_val, new_val)
  !ignored_fields.include?(field) && !(old_val.nil? && new_val == '')
end

def show

def show
  @changes = load_changes
  @change_error = 'Version ID not found.' if params[:version_id].present? && @changes.empty?
end

def user_name(whodunnit)

def user_name(whodunnit)
  user_id = Integer(whodunnit, exception: false)
  User.find_by(id: user_id)&.name || 'Unknown User'
end