package SCSite::SidebarFilter;

use Moo;

with 'SCSite::Filter';

has _page_set => (is => 'ro', required => 1);

sub new_from_site {
  my ($class, $site) = @_;
  $class->new(_page_set => $site->pages);
}

sub _latest_news {
  shift->_page_set
       ->get({ path => '/news/archive' })
       ->children(at_depth => 3)
       ->latest(2)
       ->flatten;
}

sub _latest_news_archives {
  shift->_page_set
       ->get({ path => '/news/archive' })
       ->${\sub { # archive page plus three latest per-month
           my $o = shift;
           ($o, $o->children(at_depth => 2)->latest(3)->flatten)
         }};
}

sub _latest_blog_posts {
  shift->_page_set
       ->get({ path => '/blog' })
       ->children(min_depth => 2, max_depth => 0)
       ->latest(4)
       ->flatten;
}

has _sidebar_structure => (is => 'lazy');

sub _build__sidebar_structure {
  my ($self) = @_;
  [
    [ 'NEWS',
      [ 'Latest News Items', $self->_latest_news ],
      [ 'Archives', $self->_latest_news_archives ],
    ],
    [ 'BLOGS',
      [ 'Latest Blog Posts', $self->_latest_blog_posts ],
    ],
  ];
}

sub _filter_stream {
  my ($self, $stream) = @_;
  my @blocks = @{$self->_sidebar_structure};
  $stream->select('.sidebar.block')->repeat([
             map { my ($t, @seg) = @$_; sub {
               $_->select('.sidebar.title')->replace_content($t)
                 ->select('.sidebar.segment')->repeat([
                     map { my ($s, @e) = @$_; sub {
                       $_->select('.sidebar.subtitle')->replace_content($s)
                         ->select('.sidebar.entries')->repeat_content([
                             map { my $e = $_; sub {
                               $_->select('.entry.title')
                                 ->replace_content($e->title)
                                 ->select('.entry.link')
                                 ->set_attribute(href => $e->path)
                             } } @e
                           ])
                     } } @seg
                   ])
             } } @blocks
           ])
}

1;
