package LIMS::Controller::Roles::SessionStore;

=begin
********************************************************************************
this is potentially dangerous - an update to another record done in a 2nd tab
before submission of update in 1st tab will replace session data belonging to
record in 1st tab - check retrieved request id matches form submission
********************************************************************************
=cut

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

# adapted from CAP::Stash:
sub session_store {
    my $self = shift;

    # First use?  Create new __SESSION_STORE__PARAMS
    $self->{__SESSION_STORE__PARAMS} ||= {};

    if (@_) {
		return $self->error( 'Need even number of args to session_store()' )
            if @_ % 2;

        my %stash = @_; # convert to hash

        while ( my ( $key, $val ) = each %stash ) {
            $self->{__SESSION_STORE__PARAMS}->{$key} = $val;
        }
    }

    return $self->{__SESSION_STORE__PARAMS};
}

#-------------------------------------------------------------------------------
# **** need to check retrieved request id matches form submission - see above ***
sub session_store_request_edit_data {
	my ($self, $request_data) = @_;

	# $request_data->{data} = LIMS::DB::Request object output from
	# Model::Request::get_single_request()
	my $data = $request_data->{data}; # $self->debug($data->as_tree);
	# $self->session_store( _data => $data ); # works but lots of extraneous stuff

	{ # request id:
		$self->session_store( request_id => $data->id );
	}
	{ # patient id:
		my $patient_id = $data->patient_case->patient_id;
		$self->session_store( patient_id => $patient_id );
	}
	{ # patient_case id:
		my $patient_case_id = $data->patient_case->id;
		$self->session_store( patient_case_id => $patient_case_id );
	}
	{ # unit_number:
		my $unit_number = $data->patient_case->unit_number;
		$self->session_store( unit_number => $unit_number );
	}
	{ # referral_source:
		my $referral_source = $data->patient_case->referral_source->display_name;
		$self->session_store( referral_source => $referral_source );
	}
	{ # referral_source_id:
		my $referral_source_id = $data->patient_case->referral_source_id;
		$self->session_store( referral_source_id => $referral_source_id );
	}
	{ # referrer_department_id:
		my $referrer_department_id = $data->referrer_department_id;
		$self->session_store( referrer_department_id => $referrer_department_id );
	}
	{ # parent_organisation_id:
		my $parent_organisation_id = $data->referrer_department->parent_organisation_id;
		$self->session_store( parent_organisation_id => $parent_organisation_id );
	}
	{ # referrer_code:
		my $referrer_code = $data->referrer_department->referrer->national_code;
		$self->session_store( referrer_code => $referrer_code );
	}
	{ # referrer_name:
		my $referrer_name = $data->referrer_department->referrer->name;
		$self->session_store( referrer_name => $referrer_name );
	}
	{ # specimen_map:
		# specimen_map is hashref of request_id => hashref of arrayrefs of specimen data:
		my $specimen_map = $request_data->{specimen_map}->{$data->id}->{sample_code};
		my $specimen_code = join ', ', @$specimen_map; # warn $specimen_code;
		$self->session_store( specimen_code => $specimen_code );
	}
    # specimen taken date:
    if ( my $request_specimen_detail = $data->request_specimen_detail ) {
		if ( my $date = $request_specimen_detail->specimen_date ) { # warn Dumper $date->as_tree;
			my %data = map +($_ => $date->$_), qw(year month day hour minute); # warn Dumper \%data;
			$self->session_store( specimen_date => \%data );
		}
    }
	# clinical trial data:
	if ( my $request_trial = $data->request_trial ) {
		my $trial_id   = $request_trial->trial_id;
		my $trial_name = $request_trial->trial->trial_name;
		my $patient_id = $data->patient_case->patient_id;

		# might have a trial_number:
		my $trial_number =
			$self->model('ClinicalTrial')->get_trial_number($patient_id, $trial_id);

		$self->session_store(
			trial_id     => $trial_id,
			trial_name   => $trial_name,
			trial_number => $trial_number,
		);
	}
	# request options:
	if ( my %data = %{ $request_data->{request_options} } ) { # warn Dumper \%data;
		while ( my( $option, $d ) = each %data ) { # warn Dumper [ $option, $d ];
			$self->session_store( $option => $d->{is_selected} ); # don't need 'is_active'
		}
	}
	# request consent:
	if ( my %data = %{ $request_data->{request_consent} } ) { # warn Dumper \%data;
		while ( my( $option, $value ) = each %data ) {
			$self->session_store( $option => $value );
		}
	}
	# external_ref:
	if ( $data->request_external_ref ) {
		my $external_ref = $data->request_external_ref->external_reference;
		$self->session_store( external_reference => $external_ref );
	}

	# store data in session with accessor name:
	$self->_session_store_data('_request_edit_data');
}

#-------------------------------------------------------------------------------
sub session_store_hashref { # generic method to store a simple hashref
	my ($self, $data, $keyname) = @_; # hashref, scalar

	$self->session_store( $_ => $data->{$_} ) for keys %$data;
	$self->_session_store_data($keyname);
}

#-------------------------------------------------------------------------------
# only used by .tt for search_link so no danger from 2nd tab (see top of file)
sub session_store_form_data {
	my ($self, $form_data) = @_; # hashref

	while ( my($field, $val) = each %$form_data ) {
		next unless $val;
		$self->session_store( $field => $val );
	}

	# store data in session with accessor name:
	$self->_session_store_data('_patient_merge_data');
}

#-------------------------------------------------------------------------------
sub _session_store_data {
	my ($self, $accessor_name) = @_;

	# retrieve final session_store from object:
	my $session_store = $self->session_store; # $self->debug($session_store);

	# store snap-shot data in session - overwrite any existing data as necessary:
	$self->session->param( $accessor_name => $session_store );
}

1;
