package LIMS::Model::HMRN::Data;

use Moose::Role;
requires 'patient_id';

use Data::Dumper;

# ------------------------------------------------------------------------------
# all diagnoses with ICDO3 designation for patient.id(s) (NB includes /1, /3, /6):
sub all_icdo3_diagnoses { 
    my ($self, $pid) = @_; # warn Dumper $pid; # $pid can be int or arrayref
    
	my @tables = qw( patients diagnoses );	
	my $relationships = $self->get_relationships(\@tables);
	
	my %args = (
		query => [
            patient_id => $pid,
            'request_report.diagnosis.icdo3' => { ne => undef }, # icdo3 col not null
        ],
		require_objects => $relationships,        
	);
	my $data = LIMS::DB::Request::Manager->get_requests(%args);
	
	return $data;
}

# ------------------------------------------------------------------------------
sub event_dates {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

    my $sql = q!select t2.description, t1.date from hmrn.patient_event t1
		join hmrn.events t2 on t1.event_id = t2.id where patient_id = ?!;
    my $events = $dbix->query($sql, $patient_id)->hashes; # warn Dumper $events;

	for (@$events) {
		my $event = $_->{description};
		my $date  = $self->inflate_mysql_date_to_datetime($_->{date});
		$data->{event_dates}{$event} = $date;
	}
}

# ------------------------------------------------------------------------------
sub mdt_dates {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

    my $sql = q!select id, date from hmrn.patient_mdt_dates where 
        patient_id = ? order by date!;
    my $dates = $dbix->query($sql, $patient_id);
    
    while ( my $vals = $dates->hash ) {	# inflate 'date' val to DT object:
    	$self->inflate_mysql_dates_to_datetime($vals, ['date']);
        push @{ $data->{mdt_dates} }, $vals;
    }
}

# ------------------------------------------------------------------------------
sub antecedent_events {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

    { # antecedent_events:
        my $sql = q!select event_id from hmrn.patient_antecedent where patient_id = ?!;
        my $event_id = $dbix->query($sql, $patient_id)->list;
        $data->{antecedent}{event_id} = $event_id;
	}
	{	# previous radio- & chemo-therapies:
		my $sql = q!select therapy from hmrn.patient_prior_therapies where patient_id = ?!;
		my $tx = $dbix->query($sql, $patient_id)->flat; # warn Dumper $tx;
		my %data = map { $_ => 1 } @$tx; # warn Dumper \%data;
		$data->{antecedent}{prior_tx} = \%data; # part of antecedent/prior tx set
	}
}

# ------------------------------------------------------------------------------
sub referral_pathway {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

	my @dates = qw(referral_date date_first_seen);
	my $sql = $self->sql_lib->retr('hmrn_patient_referral_pathway');

	my $query = $dbix->query($sql, $patient_id);
	while ( my $vals = $query->hash ) { # warn Dumper $vals; # dates to datetime:
		$self->inflate_mysql_dates_to_datetime($vals, \@dates);
		push @{ $data->{referrals} }, $vals; # add to referrals array
	}
}

# ------------------------------------------------------------------------------
sub treatment {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

	my $sql = $self->sql_lib->retr('hmrn_patient_treatment_data');
	my $tx = $dbix->query($sql, $patient_id);
	while ( my $vals = $tx->hash ) { # warn Dumper $vals; # dates to datetime:
		$self->inflate_mysql_dates_to_datetime($vals, [ qw(start_date end_date) ]);
		push @{ $data->{treatments} }, $vals; # add to treaments array
	}
}

# ------------------------------------------------------------------------------
sub data_params {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

	my $sql = $self->sql_lib->retr('hmrn_all_patient_params');
	my $query = $dbix->query($sql, $patient_id);
	while ( my $vals = $query->hash ) {
		my $param_name = $vals->{param_name};
		my $category   = $vals->{category};

		$data->{params}{$category}{$param_name} = $vals->{result};
	}
}

# ------------------------------------------------------------------------------
# which dataset(s) do we have - skip 'promiscuous' params & autoincrement category counter:
sub dataset_type {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

    my $sql = $self->sql_lib->retr('hmrn_non_unique_params');
    my @non_unique_params = $dbix->query($sql)->flat;

    my $param_data = $data->{params};

    CATEGORY: # for each category (precursor, myeloid, etc):
	while ( my($category, $ref) = each %$param_data ) {
		PARAM: # for each data param (albumin, Hb, etc):
		while ( my ($param, $result) = each %$ref ) {
			# skip any params shared by >1 category:
			next PARAM if grep $param eq $_, @non_unique_params;
			# increment category_has_data count for category:
			$data->{category_has_data}{$category}++;
		}            
    } # warn Dumper \$data;
}

# ------------------------------------------------------------------------------
sub imaging_data {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;

    { # imaging events:
        my $query = $dbix->select('hmrn.patient_imaging_event',
            [ qw(id scan_type dataset stage date) ],
            { patient_id => $patient_id } );
    
		while ( my ($id, $scan_type, $dataset, $stage, $date) = $query->list ) {
            my %h = (
                event_id => $id,
                stage => $stage,
                date  => $date,
            );
            $self->inflate_mysql_dates_to_datetime(\%h, ['date']);
            $data->{imaging}{$scan_type}{$dataset}{$_} = $h{$_} for keys %h;
        }
    }
    { # imaging sites:
		my $sql = $self->sql_lib->retr('hmrn_patient_imaging');
		my $query = $dbix->query($sql, $patient_id);
		while ( my ($scan_type, $dataset, $option_id) = $query->list ) {
		   $data->{imaging}{$scan_type}{$dataset}{site_opts}{$option_id}++;      
		}
	}
	{ # other (free-text) details:
        my $sql = q!select scan_type, dataset, details from
            hmrn.patient_imaging_other io join hmrn.patient_imaging_event ie on
            io.imaging_event_id = ie.id where ie.patient_id = ?!;
        my $query = $dbix->query($sql, $patient_id);
		while ( my ($scan_type, $dataset, $detail) = $query->list ) {
			$data->{imaging}{$scan_type}{$dataset}{other} = $detail;
		}
    }
    { # SUV & deauville data - only exists for pet scan:
        my $sql = q!select scan_type, dataset, param, result from
            hmrn.patient_pet_score ps join hmrn.patient_imaging_event ie on
            ps.imaging_event_id = ie.id where ie.patient_id = ?!;
        my $query = $dbix->query($sql, $patient_id);
		while ( my ($scan_type, $dataset, $param, $result) = $query->list ) {
            $data->{imaging}{$scan_type}{$dataset}{$param} = $result;
        }
    }
}

# ------------------------------------------------------------------------------
sub comments {
    my $self = shift;
    my $data = shift;

    my $patient_id = $self->patient_id;

	my $dbix = $self->lims_dbix;
    
	my $sql = 'select * from hmrn.patient_comments where patient_id = ?';
	my $comment = $dbix->query($sql, $patient_id)->hash;
	$self->inflate_mysql_timestamp_to_datetime($comment, ['timestamp']);
	$data->{params}{comment} = $comment;
}

# ------------------------------------------------------------------------------
# calculated indices (IPI, FLIPI, HIPI, etc):
sub calculated_indices {
    my $self = shift;
    my $data = shift; # warn Dumper $data;

    my $patient_id = $self->patient_id;

    # use initial CT scan data for staging:
    if ( my $initial_scan = $data->{imaging}->{ct}->{1} ) { # warn Dumper $initial_scan;
        my %args = (
            patient_id   => $patient_id,
            params_data  => $data->{params},
            initial_scan => $initial_scan,
            option_maps  => $data->{maps},
        ); # warn Dumper $data->{params};

        # all calculations handled by Model::HMRN::PrognosticIndicator:
        my $indices = $self->prognostic_indicators(\%args);

        $data->{params}{indices} = $indices; # warn Dumper $indices;
    }
}

1;
