package LIMS::Model::Report;

use Moose;
extends 'LIMS::Model::Base';
with (
    'LIMS::Model::Roles::RequestUpdate',
    'LIMS::Model::Roles::ReportUpdate', # uses L::M::R::Outreach
);

use namespace::clean -except => 'meta';

has form_data => ( is => 'rw', isa => 'HashRef', default => sub { {} } );

__PACKAGE__->meta->make_immutable;

use Data::Dumper;

# ------------------------------------------------------------------------------
sub get_report {
    my ($self, $request_id) = @_;

    my $report = LIMS::DB::RequestReport->new(request_id => $request_id)
        ->load(speculative => 1);

    return $report;
}

# ------------------------------------------------------------------------------
sub get_draft_reports {
    my ($self, $request_id) = @_;

    my @args = (
        query => [ request_id => $request_id ],
        require_objects => 'user',
    );
    my $o = LIMS::DB::RequestDraftReport::Manager->get_objects(@args);
    return $o;
}

# ------------------------------------------------------------------------------
sub get_draft_report {
    my ($self, $args) = @_; # href of request_id & user_id = PK of db table

    my $data = LIMS::DB::RequestDraftReport->new(%$args)
        ->load( with => [ qw/diagnosis user secondary_diagnosis/ ]);
    return $data;
}

# ------------------------------------------------------------------------------
sub save_draft_report {
    my ($self, $data) = @_; # warn Dumper $data;

    my $request_id = $data->{_request_id}; # warn $request_id;
    my $username   = $self->user_profile->{username};

    # get draft_report_user from username or create new:
    my $draft_report_user = LIMS::DB::DraftReportUser->new(username => $username)
        ->load_speculative || $self->create_draft_report_user; # returns new user object

	my $o = LIMS::DB::RequestDraftReport->new(request_id => $request_id);
    my @cols = grep $_ !~ /(creat|updat)ed|request_id/, # $data->{request_id} is null
        $o->meta->column_names; # warn Dumper \@cols;

	$o->$_($data->{$_} || undef) for @cols; # undef to allow deletes eg secondary_diag
    $o->user_id($draft_report_user->id); # warn Dumper $o->as_tree;

    my $now = LIMS::Local::Utils::time_now();
    $o->updated_at($now); # warn Dumper $o->as_tree;

    my $db = $self->lims_db;
	# don't need return value unless error (changes_only at least preserves timestamp):
    return $db->do_transaction( sub { $o->insert_or_update(changes_only=>1) } )
        ? 0 : 'save_draft_report() error - ' . $db->error;
}

# ------------------------------------------------------------------------------
sub create_draft_report_user {
    my $self = shift;

    my $profile = $self->user_profile;

    my $user = LIMS::DB::DraftReportUser->new;
    $user->$_($profile->{$_})
        for qw(username first_name last_name password email);
    $user->save;
    return $user;
}

# ------------------------------------------------------------------------------
sub get_report_data {
    my ($self, $request_id) = @_;

    my $report = LIMS::DB::RequestReport->new(request_id => $request_id)
        ->load(with => ['request', 'diagnosis']);

    return $report;
}

# ------------------------------------------------------------------------------
sub update_report {
    my $self = shift;
    my $data = shift; # $self->debug($data);

	$self->form_data($data); # warn Dumper $data;

    # required params: status, diagnosis_id, specimen_quality, _request_id
    # possible params: general_notes, morphology, comment, clinical_details,
    # gross_decription, revision, _diagnosis_id, secondary_diagnosis_id

    my $db = $self->lims_db; # ie LIMS::DB->new_or_cached;

    my $update = sub {
        { # if params 'diagnosis_id' & '_diagnosis_id' & both different, archive:
            my $has_original_diagnosis = $data->{_diagnosis_id}; # optional field

            if ( $has_original_diagnosis && $self->has_changed_diagnosis ) {
                $self->do_request_diagnosis_history();
            }
        }

        # report section:
        $self->do_request_report(); # Roles::ReportUpdate

        # general_notes:
        $self->update_general_notes($data);

        # others (additional options):
        $self->do_additional_options();

        # request_history (actions set in Role::ReportUpdate):
        $self->do_request_history();
    };
#$self->set_rose_debug(1);

	my $ok = $db->do_transaction($update);
#$self->set_rose_debug(0);

	# don't need return value unless error:
    return $ok ? 0 : 'update_report() error - ' . $db->error;
}

# ------------------------------------------------------------------------------
sub log_authorisation_diagnosis {
    my ($self, $data) = @_; # warn Dumper $data; return;

    my $update_success = LIMS::DB::RequestAuthorisationDiagnosis->new(
        report_diagnosis_id => $data->{_report_diagnosis_id},
        auth_diagnosis_id   => $data->{diagnosis_id},
        request_id          => $data->{_request_id},
        user_id             => $self->user_profile->{id},
    )->load_or_insert; # or 'insert_or_update()' if edits allowed

    # return $o->error if $o->error; # no - get "error" if load() part fails
    return $update_success ? 1 : 0; # probably same as: return $update_success
}

1;
