package LIMS::Controller::Roles::History;

use Moose::Role;

has history => (	
    is         => 'ro',
    isa        => 'ArrayRef[Str]',
	lazy       => 1, # needed to avoid 'Can't use an undefined value as an ARRAY reference'
    default    => sub { [] },
	traits     => ['Array'],
	handles => {
		add_history     => 'push',
		count_histories => 'count',
		all_histories   => 'elements',
	},
);

has formatted_output => (
    is         => 'ro',
    isa        => 'ArrayRef[HashRef]',
	lazy       => 1, # needed to avoid 'Can't use an undefined value as an ARRAY reference'
    default    => sub { [] },
	traits     => ['Array'],
	handles => {
		add_to_output => 'push',
		# join_output   => 'join', # want to return array(ref), not str
	},
);

has archive => (	
    is         => 'ro',
    isa        => 'ArrayRef[LIMS::DB::RequestReportHistory]',
	lazy       => 1, # needed to avoid 'Can't use an undefined value as an ARRAY reference'
    default    => sub { [] },
	traits     => ['Array'],
	handles => {
		add_archive  => 'push',
		all_archives => 'elements',
	},
);

use Data::Dumper;

#-------------------------------------------------------------------------------
# accepts request.id:
sub get_lab_test_history {
	my ($self, $request_id) = @_;

    my $history =
        $self->model('History')->get_lab_test_history($request_id);

    return $history;
}

#-------------------------------------------------------------------------------
# accepts patient.id:
sub get_patient_history {
	my ($self, $patient_id) = @_;

    my $history =
        $self->model('History')->get_patient_history($patient_id);

    return $history;
}

#-------------------------------------------------------------------------------
# accepts patient.id:
sub get_demographic_history {
	my ($self, $patient_id) = @_;

    my $history =
        $self->model('History')->get_demographic_history($patient_id);

    return $history;
}

#-------------------------------------------------------------------------------
# accepts request.id:
sub get_request_history {
	my ($self, $request_id) = @_;

    my $history =
        $self->model('History')->get_request_history($request_id);

    return $history;
}

#-------------------------------------------------------------------------------
# accepts request.id:
sub get_diagnosis_history {
	my ($self, $request_id) = @_;

    my $history =
        $self->model('History')->get_diagnosis_history($request_id);

    return $history;
}

#-------------------------------------------------------------------------------
# accepts request oject:
sub get_deletion_history {
	my ($self, $request) = @_; # request object

    my $history = $self->model('History')->get_deletion_history($request);
    return $history;
}

#-------------------------------------------------------------------------------
sub history_log_event {
	my ($self, $args) = @_;
	
	my $request_id = $args->{request_id};
	my $event = $args->{event};
	
	{ # don't log events from lab-staff:
		my $user_profile = $self->user_profile; # warn Dumper $user_profile;
		my $service_name = $self->cfg('settings')->{lab_name_abbreviation};

		return 0 if ($user_profile->{user_location}->{location_name} eq $service_name);
	}
	
	my %data = (
		request_id => $request_id,
		session    => $self->session,
		event      => $event,
	);
	
	my $rtn = $self->model('History')->do_log_event(\%data);
	warn $rtn if $rtn; # no need for user to see error 
}

#-------------------------------------------------------------------------------
sub diff_report_changes { 
    my ($self, $args) = @_;
	
	my $request_id = $args->{request_id};
	my $report_field = $args->{field};

	{ # previous entries from archive:
		my $archive	= $self->model('History')->get_report_history($args);

        return 0 unless @$archive; # no entries in request_report_history		

		for (@$archive) { # $self->debug($_);
			$self->add_history($_->content); 
			$self->add_archive($_);
		}
	}
	{ # current comment:
		my $report = $self->model('Report')->get_report($request_id);
		$self->add_history($report->$report_field); 
	}
	
	my $count = $self->count_histories; # warn $count;
	my @histories = $self->all_histories;
	
	# send the first two entries (original comment & 1st modification) to
	# do_diff() and _get_original_report_details():
	{
		my $title = $self->_get_original_report_details($request_id);		
		my $diffs = $self->do_diff(@histories[0,1]);
			
		$self->add_to_output({ title => $title, diff => $diffs });
	}
	
	if ($count > 2) { # we have more than one entry in comment_archive:
		# send rest to do_diff() and _get_revision_details():
		for my $i(1 .. $count - 2) {
			my $title = $self->_get_revision_details($i);
			my $diffs = $self->do_diff(@histories[$i, $i + 1]);		
				
			$self->add_to_output({ title => $title, diff => $diffs });
		}		
	}

	return $self->formatted_output;	
}

#-------------------------------------------------------------------------------
sub _get_request_history {
	my ($self, $request_id) = @_;
	
	my $history = $self->model('History')->get_request_history($request_id);		
	my %map = map { $_->action => $_ } @$history;
	return \%map;
}

#-------------------------------------------------------------------------------
sub _get_original_report_details {
	my ($self, $request_id) = @_;

    # report history:
	my $request_history_map = $self->_get_request_history($request_id);
	# get 1st entry from archive:
	my $archive_entry = $self->archive->[0];
	
	my $title = sprintf 'Original by %s %s on %s, modified by %s %s on %s', 
		ucfirst $request_history_map->{reported}->user->first_name,
		ucfirst $request_history_map->{reported}->user->last_name,
		$request_history_map->{reported}->time->strftime('%d.%b.%Y @ %H:%M'),
		
		ucfirst $archive_entry->user->first_name,
		ucfirst $archive_entry->user->last_name,
		$archive_entry->time->strftime('%d.%b.%Y @ %H:%M');

	return $title;
}

#-------------------------------------------------------------------------------
sub _get_revision_details {
	my ($self, $archive_index) = @_;
	
	# get indexed entry from archive:
	my $archive_entry = $self->archive->[$archive_index];

	my $title = sprintf 'Further modified by %s %s on %s',
		ucfirst $archive_entry->user->first_name,
		ucfirst $archive_entry->user->last_name,
		$archive_entry->time->strftime('%d.%b.%Y @ %H:%M');

	return $title;		
}

1;
