package LIMS::Controller::Roles::Misc;

use Moose::Role;
use Data::Dumper;

has blood_tube_cfg => ( is => 'ro', isa => 'HashRef', lazy_build => 1 );

# ------------------------------------------------------------------------------
sub get_unique_ids {
	my $self = shift;
	my $data = shift; # arrayref
	
	my %h;

	foreach(@$data) { # warn Dumper $_->as_tree;
		map { # may contain duplicate request.id's:
			my $request_id = $_->request->id;
			$h{$request_id}++
		} @$data;
	}
	
	my @unique_ids = keys %h; # $self->debug(\%request_ids);

	return \@unique_ids;
}

# ------------------------------------------------------------------------------
sub redirect_after_edit_success {
	my ($self, $link) = @_;
	
    $self->flash( info => $self->messages('action')->{edit_success} );
    return $self->redirect( $self->query->url . $link );	
}

# ------------------------------------------------------------------------------
sub redirect_after_create_success {
	my ($self, $link) = @_;
	
    $self->flash( info => $self->messages('action')->{create_success} );
    return $self->redirect( $self->query->url . $link );	
}

# ------------------------------------------------------------------------------
sub get_lab_test_results_for_lab_section {
	my $self = shift;
	my $args = shift;
	
	my $lab_section_id = $args->{lab_section_id};	
	my $request_id     = $args->{request_id};  # scalar / arrayref
	
	# get lab-tests for lab-section where test-type = test & has_results = yes:
	my %args = (
		lab_section_id => $lab_section_id,
		test_type   => 'test',
		has_results => 'yes',
		is_active   => 'yes',
	); # warn Dumper \%args;
	
	my $lab_tests = $self->model('LabTest')->get_section_lab_tests(\%args);	
	my @lab_test_ids = map { $_->id } @$lab_tests; # warn Dumper \@lab_test_ids;
	return 0 unless @lab_test_ids; # can't pass empty list to model
	
	{ # now get lab-test results for all request ids:
		my %args = (
			request_id  => $request_id, # scalar / arrayref
			lab_test_id => \@lab_test_ids,
		);
		
		my $results	= $self->model('Local')
			->get_selected_request_lab_test_results(\%args);
		# warn Dumper $results;
		
		my %results_map = ();
		map {
			my $req_id   = $_->request_id; 
			my $lab_test = $_->lab_test->test_name;
			my $result   = $_->result;
			
			$results_map{$req_id}{$lab_test} = $result;
		} @$results; # warn Dumper \%results_map;
		
		return \%results_map;
	}
}

# ------------------------------------------------------------------------------
sub get_lab_test_for_unique_test_name {
	my ($self, $test_name) = @_;
	
	my $lab_test
		= $self->model('LabTest')->get_lab_section_for_test_name($test_name);

	return 0 if scalar @$lab_test > 1;
	
	return $lab_test->[0];
}

# ------------------------------------------------------------------------------
sub extract_patients_and_locations {
	my ($self, $cases) = @_;
	
	my %cases_map = (); # hash for patient.id => referral details
	my @patients  = (); # array of unique patients from $case_iterator
	my %seen      = (); # to facilitate a unique patients list
	
	CASE:
	for my $case (@$cases) {
		my $pid = $case->patient_id; # $self->debug($pid);
	
		push @{ $cases_map{$pid} }, $case->as_tree;
		
		# only need patient details once:
		push @patients, $case->patient->as_tree(deflate => 0) unless $seen{$pid}++;		
	}
	
	return {
		cases_map => \%cases_map,
		patients  => \@patients,
	}
}

# ------------------------------------------------------------------------------
# provides callback for template to find required blood tube for Outreach practice:
sub get_blood_tube_type {
    my ($self, $post_code) = @_; # warn Dumper $post_code;
    
    my $cfg = $self->blood_tube_cfg;
    
    # define default container in case new GP practice registered:
    my $DEFAULT = 'monovette'; # only LS & DN get vacutainers
    
    return $DEFAULT if ! $post_code; # eg no demographics entered yet
    
    # get post-code area from 1st 2 chars of post_code (LS, DN, S7, etc):
    my ($post_code_area) = $post_code =~ /\A(\w{2})/; # warn Dumper $post_code_area;

    # get container for post-code area:
    my $container = $cfg->{$post_code_area};
        warn 'NO CONTAINER CONFIGURED FOR ' . $post_code unless $container;
    return $container || $DEFAULT;
}

# -------------------------------------------------------------------------------------
sub get_icdo_category {
    my $self = shift;
    
    my $args = { require_objects => ['diagnostic_category'] };
    my $o = $self->model('Base')->get_objects_iterator('ICDOCategory', $args);
    
    my %map;
    while (my $row = $o->next) { 
        # only want sub-categories:
        next unless $row->diagnostic_category->category_type eq 'sub';
        $map{$row->icdo3} = $row->diagnostic_category->description;
    }
    return \%map;
}

# ------------------------------------------------------------------------------
# using redirect can't use check_rm() method so need to load err msg into flash:
sub format_dfv_msg {
    my $self = shift;
    my $dfv  = shift;
    
    my $reformat = sub {
        my $str = shift; # warn $str;
        $str =~ s/(_id)\Z//; # gp_id, practice_id, etc
        $str =~ s/_/ /g; # warn $str;
        return $str;
    };
    $self->tt_params( reformat => $reformat );
    
    my $tmpl = 'site/snippets/flash_dfv_msg.tt';
    my $html = $self->tt_process($tmpl, { dfv => $dfv });
    return $$html;
}

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

	# get all status options (supply 'key'):
	my $all_status_options = $self->lab_test_status_options_map('description'); 

	my $section_status_options
        = $self->model('LabSection')->get_section_status_options($lab_section_id);
    
	# need to add 'new' to options:
    my @options = (
        {
            description => 'new',
            id => $all_status_options->{new}->{id},
        }
    );
    for (@$section_status_options) {
        push @options, 
            {
                description => $_->status_option->description,
                id => $_->status_option_id,
            };
    }
	return \@options;
}

# ------------------------------------------------------------------------------
sub _build_blood_tube_cfg {
	my $self = shift;
	my $cfg = $self->get_yaml_file('blood_tube'); # warn Dumper $cfg;
	return $cfg;
}

1;