package LIMS::Controller::History;

use Moose;
BEGIN { extends 'LIMS::Base'; }
with (
    'LIMS::Controller::Roles::Diff',
    'LIMS::Controller::Roles::DataMap',
    'LIMS::Controller::Roles::History', # get_*_history()
);
__PACKAGE__->meta->make_immutable(inline_constructor => 0);

use Data::Dumper;
# ------------------------------------------------------------------------------
# default() should never be called direct - redirect to start page:
sub default : StartRunmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);

    return $self->redirect( $self->query->url );
}

# ------------------------------------------------------------------------------
sub load : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);

    return $self->forbidden() unless $self->user_can('view_history');
    
    my $request_id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);

    my $request = $self->model('Request')->get_single_request($request_id);
    
    # load history data into tt_params:
    $self->_load_history_data($request);
   
    return $self->render_view('history/default.tt', { request => $request } );
}

# ------------------------------------------------------------------------------
sub previous_diagnosis : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);

    my $request_id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);

    my $previous_diagnoses
        = $self->model('History')->get_diagnosis_history($request_id);
        
    my $request_data
        = $self->model('Request')->get_patient_and_request_data($request_id);
    
    $self->tt_params(
        request_data       => $request_data,
        previous_diagnoses => $previous_diagnoses,
    );
    
    return $self->tt_process;  
}

# ------------------------------------------------------------------------------
sub report_diff : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);

    my $request_id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);
    

    my $field = $self->param('Id')
    || return $self->error('no Id passed to ' . $self->get_current_runmode);
    
    my $args = {
        request_id => $request_id,
        field      => $field,
    };

    my $changes = $self->diff_report_changes($args);
    
    unless ($changes) { # some changes not logged in request_report_history
        $self->flash( warning => $self->messages('report')->{no_report_history});
        return $self->redirect( $self->query->url . '/history/=/'.$request_id );
    }
    $self->tt_params( history => $changes );
    
    my $request = $self->model('Request')->get_single_request($request_id);
    $self->tt_params( request => $request );
    
    return $self->tt_process;
}

# ------------------------------------------------------------------------------
sub request_view : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);

    my $request_id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);
    
    my $request = $self->model('Request')->get_single_request($request_id);
    my $history = $self->model('History')->get_view_history($request_id);
    
    $self->tt_params(
        history => $history,
        request => $request,
    );
    return $self->tt_process;    
}

# ------------------------------------------------------------------------------
sub request_print : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);

    my $request_id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);
    
    my $request = $self->model('Request')->get_single_request($request_id);    
    my $history = $self->model('History')->get_print_history($request_id);
    
    $self->tt_params(
        history => $history,
        request => $request,
    );
    return $self->tt_process;    
}

# ------------------------------------------------------------------------------
sub _load_history_data {
    my ($self, $request) = @_; $self->_debug_path();

    my $request_id = $request->id; # $self->debug($request_id);
    my $patient_id = $request->patient_case->patient_id; # $self->debug($patient_id);

    my %history = (
        patient_data => $self->get_patient_history($patient_id),
        request_data => $self->get_request_history($request_id),
        demographics => $self->get_demographic_history($patient_id),
    );

    if ($history{patient_data}) { # need error_codes:
        $history{error_codes} = $self->error_codes_map;
    }
    
    # only lab staff can view lab test history:
    if ($self->is_lab_staff) {
        $history{diagnosis_data} = $self->get_diagnosis_history($request_id),
        $history{lab_test_data}  = $self->get_lab_test_history($request_id);
        $history{deletion_data}  = $self->get_deletion_history($request);
        $self->tt_params( is_lab_user => 1 ); # flag for tt
    }
    
    # sort into chronological order:
    my @chrono = (); # warn Dumper \%history_data;
    while ( my ($type, $data) = each %history ) { # warn ref $data;
        # only want request & lab_test data:
        next unless $data && grep $type eq $_, qw(request_data lab_test_data);
        for (@$data) { # warn Dumper $_->as_tree;
            my $event = $_->as_tree(deflate => 0);
            # add history type (patient, request, lab_test, etc):
            $event->{history_type} = $type;
            push @chrono, $event;          
        }
    } # warn Dumper \@chrono;
    
    $self->tt_params(
        categorical   => \%history,
        chronological => [ sort by_epoch @chrono ],
    );
}

sub by_epoch {
    return $a->{time}->epoch <=> $b->{time}->epoch || $a->{id} <=> $b->{id};
}

1;
