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 $db   = $self->hmrn_db;

    my $sql = qq!select t2.description, t1.date from $db.patient_event t1
		join $db.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 $db   = $self->hmrn_db;

    my $sql = qq!select id, date from $db.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;
    my $db   = $self->hmrn_db;

    { # antecedent_events:
        my $sql = qq!select event_id from $db.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 = qq!select therapy from $db.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->get_query('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->get_query('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->get_query('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->get_query('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 ) {
            # JD - increments 'include_shared' count when we are including 'promiscuous' params:
			$data->{category_has_data_include_shared}{$category}++;
			# 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;
    my $db   = $self->hmrn_db;

    { # imaging events:
        my $query = $dbix->select("$db.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->get_query('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 = qq!select scan_type, dataset, details from
            $db.patient_imaging_other io join $db.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 = qq!select scan_type, dataset, param, result from
            $db.patient_pet_score ps join $db.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 $db   = $self->hmrn_db;

	my $sql = "select * from $db.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;
