package LIMS::Model::PrintRun;

use Moose;
extends 'LIMS::Model::Base';
with 'LIMS::Model::Roles::Query';
use namespace::clean -except => 'meta';
__PACKAGE__->meta->make_immutable;

use Data::Dumper;
use LIMS::Local::Utils;

#-------------------------------------------------------------------------------
sub get_print_run_size {
	my ($self, $h) = @_; # warn Dumper $h; # hashref of start & end datetimes + optional cfg

	# just forward to get_print_run_request_ids and return count:
	my $ids = $self->get_print_run_request_ids($h);
	my $i = scalar @$ids; # warn $i;
	return $i;
}

#-------------------------------------------------------------------------------
sub get_print_run_request_ids {
	my ($self, $h) = @_; # warn Dumper $h; # hashref of start & end datetimes + optional cfg

    my ($start_date, $end_date) = @{$h}{ qw(start_date end_date) };

    my %print_run_args = (
        start => $start_date,
        type  => 'non-trial',
        end   => $end_date,
    );
    if ( defined $h->{offset} ) { # can be zero
		$print_run_args{$_} = $h->{$_} for qw(offset limit);
	}

    my ($sql, @bind) = $self->get_query_params(\%print_run_args); # warn $sql; warn Dumper \@bind; exit;
    my $results = $self->lims_dbix->query($sql, @bind)->flat; # warn Dumper $results;
    return $results;
}

#-------------------------------------------------------------------------------
sub get_query_params { # returns $sql & @bind params - shared with print_run.pl
    my $self = shift; # warn ref $self;
    my $args = shift; # trial or non-trial cases, start & end dates

    my $start = $args->{start}; # DT object
    my $type  = $args->{type};  # trial or non-trial
    my $end   = $args->{end};   # DT object

    my $settings = $self->lims_cfg->{settings}; # warn Dumper $settings;
    my $tbl_rels = get_tbl_rels($type);

	# set status level required for printing reports:
	my $status = $self->does_authorisation() ? 'authorised'	: 'reported'; # warn $status;

    my %query = ( 'so.description' => { -in => [ $status, 'complete' ] } );
	$query{'DATE(rr.updated_at)'} = ( $start->ymd eq $end->ymd )
		? $start->ymd # or $end->ymd, both same date
	    : { -between => [ $start->ymd, $end->ymd ] }; # warn Dumper \%query;

    my @sort_by;
    if ( $type eq 'clinical-trial' ) { # don't exclude any locations
        @sort_by = qw(ct.trial_name r.year r.request_number);
    }
    elsif ( $type eq 'non-trial' ) {
        if ( $settings->{print_run_skip_trials} ) { # skip trial cases if configured
            $query{'rt.request_id'} = undef;
        }
        # exclude any locations which don't require paper copies:
        if ( my $cfg = $self->get_yaml_file('skip_paper_reports') ) { # p $cfg;
            if ( my $org_codes = $cfg->{organisation} ) { # p $org_codes;
                $query{'po.parent_code'} = { -not_in => $org_codes };
            }
            if ( my $hospitals = $cfg->{hospital} ) { # p $hospitals;
               $query{'rs.organisation_code'} = { -not_in => $hospitals };
            }
            if ( my $departments = $cfg->{department} ) { # p $departments;
                for (@$departments) { # eg RWA/823
                    my ($location, $department) = split '/'; # p $location; p $department;
                    # 5-digits (hospital) or 3-digits (organisation) code:
                    my $site_type = length $location > 3
                        ? 'rs.organisation_code'
                        : 'po.parent_code';
                    my %h = (
                        $site_type => $location,
                        'rd.hospital_department_code' => $department,
                    );
                    push @{ $query{-not_bool} }, \%h;
                }
            }
        } # warn Dumper \%query;
        @sort_by = qw(ref.name r.year r.request_number);
    }
    my %sqla_args = (
        cols  => 'r.id',
        joins => $tbl_rels,
        where => \%query,
        order_by => \@sort_by,
    );
    if ( defined $args->{offset} ) { # can be zero
		$sqla_args{$_} = $args->{$_} for qw(offset limit);
	} # warn Dumper \%sqla_args;
    my ($sql, @bind) = $self->sqla_query(\%sqla_args);
    return ($sql, @bind);
}

sub get_tbl_rels {
    my $type = shift; # trial or non-trial cases

    my @rels = (
        # table|alias                  	# FK-PK relationship
        'requests|r' 				,	'r.referrer_department_id = rd.id'  ,
		'referrer_department|rd'	,	'rd.referrer_id = ref.id'		    ,
		'referrers|ref'				,	'r.patient_case_id = pc.id'         ,
		'patient_case|pc'			,	'rr.request_id = r.id'              ,
        'request_report_view|rr'    ,   'r.status_option_id = so.id'        ,
        'status_options|so'         ,   'pc.referral_source_id = rs.id'     ,
		'referral_sources|rs'       ,   'rs.parent_organisation_id = po.id' ,
        'parent_organisations|po'
    );
    if ( $type eq 'clinical-trial' ) { # include request_trial/clinical_trials:
        push @rels, ( 'rt.request_id=r.id' => 'request_trial|rt' ,
                      'rt.trial_id=ct.id'  => 'clinical_trials|ct' );
    }
    elsif ( $type eq 'non-trial' ) { # left join request_trial to exclude:
        push @rels, ( '=>rt.request_id=r.id' => 'request_trial|rt' );
    }
    return \@rels;
}

1;
