package EPrints::Plugin::Screen::REF::Report::REF2::View;

use EPrints::Plugin::Screen::REF::Report;
@ISA = ( 'EPrints::Plugin::Screen::REF::Report' );

use strict;

sub new
{
	my( $class, %params ) = @_;

	my $self = $class->SUPER::new(%params);

        $self->{appears} = [
                {
                        place => "ref_tools",
                        position => 200,
                }
        ];

	push @{$self->{actions}}, qw( export );

	return $self;
}

sub allow_export { shift->can_be_viewed }
sub action_export {}

sub wishes_to_export {
	$_[0]->{session}->param( "export" ) ||
	$_[0]->SUPER::wishes_to_export
}
sub export_mimetype
{
	my( $self ) = @_;

	my $plugin = $self->{processor}->{plugin};
	return $self->SUPER::export_mimetype if !defined $plugin;

	return $plugin->param( "mimetype" );
}

=item $list = $ref->users()

Returns a list of users that are returned in this report, ordered by name.

=cut

sub users
{
	my( $self ) = @_;

	my $benchmark = $self->{processor}->{benchmark};
	my $uoa = $self->{processor}->{uoa};

	my %userids;

	$benchmark->uoa_selections( $uoa )->map(sub {
		(undef, undef, my $selection) = @_;

		$userids{$selection->value( "user_id" )} = undef;
	});

	my $list = $self->{session}->dataset( "user" )->list( [keys %userids] );
	$list = $list->reorder( "name" );

	return $list;
}

sub export
{
	my( $self ) = @_;

	my $benchmark = $self->{processor}->{benchmark};
	my $uoa = $self->{processor}->{uoa};

	my $plugin = $self->{processor}->{plugin};
	return $self->SUPER::export if !defined $plugin;

	my @ids;

	$self->users->map(sub {
		(undef, undef, my $user ) = @_;

		$benchmark->user_selections( $user )->map(sub {
			(undef, undef, my $selection) = @_;

			return if $selection->uoa( $benchmark ) ne $uoa->id;

			push @ids, $selection->id;
		});
	});

	my $selections = $self->{session}->dataset( "ref_selection" )->list( \@ids );

	$plugin->initialise_fh( \*STDOUT );
	$plugin->output_list(
		list => $selections,
		fh => \*STDOUT,
	);
}

sub properties_from
{
	my( $self ) = @_;

	$self->SUPER::properties_from;

	$self->{processor}->{uoa} = $self->current_uoa;
	my $format = $self->{session}->param( "export" );
	if( $format )
	{
		my $plugin = $self->{session}->plugin( "Export::$format" );
		if( defined $plugin && $plugin->can_accept( "list/ref_selection" ) )
		{
			$self->{processor}->{plugin} = $plugin;
		}
	}
}

sub render_title
{
	my( $self ) = @_;

	my $chunk = $self->{session}->make_doc_fragment;
	$chunk->appendChild( $self->html_phrase( 'title' ) );

	my $uoa = $self->current_uoa;

	if( defined $uoa )
	{
		$chunk->appendChild( $self->{session}->make_text( ": " ) );
		$chunk->appendChild( $uoa->render_description );
	}	

	return $chunk;
}

sub render
{
	my( $self ) = @_;

	my $session = $self->{session};
	my $uoa = $self->{processor}->{uoa};

	my $chunk = $session->make_doc_fragment;

	$chunk->appendChild( $session->html_phrase( "Plugin/Screen/REF/Report:header", 
		benchmark => $self->render_current_benchmark, 
		export => $self->render_export_bar 
	) );
	
	$chunk->appendChild( $self->render_progress_bar );

	my $table = $chunk->appendChild( $session->make_element( "table",
		style => "display: none;",
		class => "ep_ref_problems"
	) );

	my $user_ids = $self->users->ids;

	my $json = "[".join(',',@$user_ids)."]";

	$chunk->appendChild( $session->make_javascript( <<"EOJ" ) );
Event.observe(window, 'load', function() {
	new REF_Report({
		ids: $json,
		step: 5,
		prefix: 'user',
		onProblems: function() { \$(\$('user_problems').parentNode).show() }
	}).execute();
});
EOJ

	# to keep things in order we provide a div to populate with the content
	foreach my $user_id (@$user_ids)
	{
		$chunk->appendChild( $session->make_element( "div",
			id => "user_".$user_id,
			class => "ref_report_box",
		) );
	}

	my $thead = $table->appendChild( $session->make_element( "thead" ) );
	my $tr = $thead->appendChild( $session->make_element( "tr" ) );
	my $th;
	$th = $tr->appendChild( $session->make_element( "th" ) );
	$th = $tr->appendChild( $session->make_element( "th" ) );
	$th->appendChild( $session->html_phrase( "datasetname_user" ) );
	$th = $tr->appendChild( $session->make_element( "th" ) );
	$th->appendChild( $session->html_phrase( "datasetname_eprint" ) );
	$th = $tr->appendChild( $session->make_element( "th" ) );
	$th->appendChild( $session->html_phrase( "history_fieldname_details" ) );

	my $tbody = $table->appendChild( $session->make_element( "tbody",
		id => "user_problems",
	) );

	# find users in the UoA but without any selections
	my $uoa_users = $session->dataset( "user" )->search(
		filters => [
			{ meta_fields => [qw( ref_uoa )], value => $uoa->id }
	])->ids;
	my %has_selections = map { $_ => undef } @$user_ids;

	foreach my $user_id (@$uoa_users)
	{
		next if exists $has_selections{$user_id};

		my $user = $session->user( $user_id );

		$tbody->appendChild( $self->render_problem_row({
			user => $user,
			problem => $self->html_phrase( "error:bad_count",
				count => $session->make_text( 0 ),
			),
		}) );

		$table->setAttribute( style => undef ); # clear display:none
	}

	return $chunk;
}

sub ajax_user
{
	my( $self ) = @_;

	my $session = $self->{session};

	$session->dataset( "user" )
	->list( [$session->param( "user" )] )
	->map(sub {
		(undef, undef, my $user) = @_;

		return if !defined $user; # odd

		my @problems;

		my $frag = $self->render_user( $user, \@problems );

		print $user->id;
		print "\n--\n";
		print $session->xhtml->to_xhtml( $frag );
		print "\n--\n";
		foreach my $problem (@problems)
		{
			print $session->xhtml->to_xhtml( $self->render_problem_row( $problem ) );
		}
		print "\n--\n";
	});
}

# frag = $plugin->render_user( $user, $problems )
sub render_user
{
	my( $self, $user, $problems ) = @_;

	my $session = $self->{session};
	my $benchmark = $self->{processor}->{benchmark};
	my $uoa = $self->{processor}->{uoa};

	my $chunk = $session->make_doc_fragment;

	my $div = $chunk->appendChild( $session->make_element( "div" ) );
	my $link = $div->appendChild( $session->make_element( "a",
		name => $user->value( "username" ),
	) );
	$link->appendChild( $user->render_citation( "ref",
		url => $self->user_control_url( $user ),
	) );

	my $selections = $benchmark->user_selections( $user );
	if( $selections->count != 4 )
	{
		push @$problems, {
			user => $user,
			problem => $self->html_phrase( "error:bad_count",
				count => $session->make_text( $selections->count ),
			),
		};
	}

	my %uoas;

	my $ol = $chunk->appendChild( $session->make_element( "ol" ) );
	$selections->map(sub {
		(undef, undef, my $selection) = @_;

		my $eprint = $session->eprint( $selection->value( "eprint_id" ) );

		my $eprint_exists = 1;
			
		my $li = $ol->appendChild( $session->make_element( "li" ) );

		if( defined $eprint )
		{
			$li->appendChild( $selection->render_citation( "report",
					user => $user,
					eprint => $eprint,
				) );
		}
		else
		{
			push @$problems, {
				user => $user,
				problem => $session->html_phrase( 'ref:error:no_eprint' )
			};

			$li->appendChild( $session->html_phrase( 'ref:error:no_eprint' ) );

			return;
		}

		push @$problems,
			$self->validate_selection( $user, $selection, $eprint );

		my @others;

		$benchmark->eprint_selections( $eprint )->map(sub {
			(undef, undef, my $other) = @_;

			my $uoaid = $other->uoa( $benchmark );
			return if $uoaid ne $uoa->id;

			return if $other->id == $selection->id;

			push @others, $other;
		});

		if( @others )
		{
			my $frag = $session->make_doc_fragment;
			foreach my $other (@others)
			{
				$frag->appendChild( $session->make_text( ", " ) )
					if $frag->hasChildNodes;
				$frag->appendChild( $session->make_text( $other->value( "user_title" ) ) );
			}
			push @$problems, {
				user => $user,
				eprint => $eprint,
				selection => $selection,
				problem => $self->html_phrase( "error:duplicate",
					others => $frag,
				),
			};
		}

		$uoas{$selection->uoa( $benchmark )} = 1;
	});

	if( scalar keys %uoas > 1 )
	{
		my $problem = $session->make_doc_fragment;
		foreach my $uoaid (keys %uoas)
		{
			$problem->appendChild( $session->make_text( ", " ) )
				if $problem->hasChildNodes;
			my $uoa = $session->dataset( "subject" )->dataobj( $uoaid );
			$problem->appendChild(
				defined $uoa ?
					$uoa->render_description :
					$session->make_text( $uoaid )
			);
		}
		push @$problems, {
			user => $user,
			problem => $self->html_phrase( "error:cross_uoa",
				uoas => $problem,
			),
		};
	}

	return $chunk;
}

# frag = $plugin->render_problem_row( $problem )
sub render_problem_row
{
	my( $self, $problem ) = @_;

	my $session = $self->{session};
	my $benchmark = $self->{processor}->{benchmark};
	my $uoa = $self->{processor}->{uoa};

	my $tr = $session->make_element( "tr" );
	my $td;

	my $link_td = $tr->appendChild( $session->make_element( "td" ) );

	my $users = $problem->{user};
	$users = [$users] if ref($users) ne "ARRAY";
	$td = $tr->appendChild( $session->make_element( "td",
		style => "white-space: nowrap",
	) );
	foreach my $user (@$users)
	{
		$td->appendChild( $session->make_element( "br" ) )
			if $td->hasChildNodes;
		$td->appendChild( $user->render_citation_link( "brief" ) );

		$link_td->appendChild( $session->make_text( " " ) )
			if $link_td->hasChildNodes;
		my $link = $link_td->appendChild( $session->render_link(
			"#".$user->value( "username" ),
		) );
		$link->appendChild( $self->html_phrase( "view" ) );
		$link_td->appendChild( $session->make_text( "/" ) );
		$link = $link_td->appendChild( $session->render_link(
			$self->user_control_url( $user ),
		) );
		$link->appendChild( $self->html_phrase( "edit" ) );
	}

	my $eprint = $problem->{eprint};
	$td = $tr->appendChild( $session->make_element( "td" ) );
	if( defined $eprint )
	{
		$td->appendChild( $eprint->render_citation( "brief",
			url => $eprint->get_control_url,
		) );
	}

	$td = $tr->appendChild( $session->make_element( "td" ) );
	$td->appendChild( $problem->{problem} );

	return $tr;
}

sub user_control_url
{
	my( $self, $user ) = @_;

	my $href = URI->new( $self->{session}->config( "userhome" ) );
	$href->query_form(
		screen => "REF::Listing",
		role => $user->id,
		_action_change_role => 1,
	);

	return $href;
}

sub validate_selection
{
	my( $self, $user, $selection, $eprint ) = @_;

	my $f = $self->param( "validate_selection" );
	return () if !defined $f;

	my @problems = &$f( @_[1..$#_], $self );

	if( @problems == 0 )
	{
		return ();
	}
	elsif( @problems == 1 )
	{
		return {
			user => $user,
			selection => $selection,
			eprint => $eprint,
			problem => $problems[0],
		};
	}
	else
	{
		my $ul = $self->{session}->make_element( "ul" );
		foreach my $problem (@problems)
		{
			my $li = $ul->appendChild( $self->{session}->make_element( "li" ) );
			$li->appendChild( $problem );
		}
		return {
			user => $user,
			selection => $selection,
			eprint => $eprint,
			problem => $ul,
		};
	}
}

sub export_plugins
{
	my( $self ) = @_;

	my $session = $self->{session};

	return $session->get_plugins(
		type => "Export",
		can_accept => "list/ref_selection",
		is_advertised => 1,
	);
}

sub hidden_bits
{
	my( $self ) = @_;

	return(
		$self->SUPER::hidden_bits,
		uoa => $self->{processor}->{uoa}->id,
	);
}

1;

