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_request_ids {
	my $self = shift;
	my $data = shift; # warn Dumper $data; # arrayref of DB:: objects

	my %h = map { $_->request->id => 1 } @$data; # $self->debug(\%h);
	my @unique_ids = keys %h; # $self->debug(\@unique_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_edit_successes { # same as above but for multiple records
	my ($self, $link) = @_;

    $self->flash( info => $self->messages('action')->{edit_successes} );
    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 load_diagnosis_context_warnings { # just sets tt_params
	my $self = shift;

	{ # list of all context_warnings:
		my $context_warnings = $self->model('Diagnosis')
			->get_all_context_warnings({ sort_by => 'description'});
		$self->tt_params( context_warning_opts => $context_warnings );
	}
	{ # diagnosis_context_warnings:
		my $o = $self->model('Diagnosis')->get_diagnosis_context_warnings;
		my %map = map { $_->diagnosis->name => $_->as_tree } @$o;
		$self->tt_params( diagnosis_context_warnings => \%map );
	}
	{ # diagnoses:
		my $diagnoses_map = $self->diagnoses_map('name'); # send key
		$self->tt_params( diagnoses => $diagnoses_map );
	}
    return 0;
}

# ------------------------------------------------------------------------------
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;
