package LIMS::Model::LabSection;

use strict;

use base 'LIMS::Model::Base';

use Data::Dumper;

#-------------------------------------------------------------------------------
sub get_lab_section {
    my $self = shift;
    my $id   = shift;

    my $section = LIMS::DB::LabSection->new(id => $id)->load; # DEBUG $test;

    return $section;
}

#-------------------------------------------------------------------------------
sub get_lab_section_by_name {
    my $self = shift;
    my $name = shift;

    my $section = LIMS::DB::LabSection->new(section_name => $name)->load; # DEBUG $test;

    return $section;
}

#-------------------------------------------------------------------------------
sub get_lab_sections {
    my $self   = shift;
    my $params = shift || {};

    $params->{sort_by} ||= 'section_name';

    # get lab_section rows as arrayref:
    my $data = LIMS::DB::LabSection::Manager->get_lab_sections(%$params); # $self->debug($data);

    return $data;
}

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

    my $o = LIMS::DB::LabSection::Manager->get_lab_sections(
        query => [ 'lab_tests.has_results' => 'yes' ],
        require_objects => [ 'lab_tests' ],
        distinct => 1,
    );
}

#-------------------------------------------------------------------------------
sub get_section_status_options {
    my ($self, $lab_section_id) = @_;

    my %args = (
        query => [ lab_section_id => $lab_section_id ],
        require_objects => 'status_option',
        sort_by => 'position',
    );

    my $status_options = LIMS::DB::LabSectionStatusOption::Manager
        ->get_lab_section_status_option(%args);

    return $status_options;
}

#-------------------------------------------------------------------------------
sub get_section_sample_types {
    my ($self, $lab_section_id) = @_;

    my %args = ( query => [ lab_section_id => $lab_section_id ] );
    my $o = LIMS::DB::LabSectionSampleType::Manager
        ->get_lab_section_sample_types(%args);
    return $o;
}

#-------------------------------------------------------------------------------
sub get_labsection_remote_system_ids {
    my ($self, $request_id) = @_; # DEBUG $section; return;

    my %args = (
        query => [ request_id => $request_id ],
        require_objects => 'lab_section',
    );

    my $remote_system_ids = LIMS::DB::RequestLabSectionForeignID::Manager
        ->get_request_lab_section_foreign_ids(%args);

    return $remote_system_ids;
}

#-------------------------------------------------------------------------------
sub update_section_status_options {
    my $self = shift;
    my $data = shift; # warn Dumper $data;

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

    my $option_data = $data->{option_data};

    my $update = sub {
        # first clear existing data:
        LIMS::DB::LabSectionStatusOption::Manager->delete_lab_section_status_option(
            where => [ lab_section_id => $data->{section_id} ],
        );

        if ( ref $option_data eq 'ARRAY' ) {
            DATA: for my $d (@$option_data) { # warn Dumper $d;
                next DATA unless defined $d; # empty entries submitted
                my ($option_id, $position) = split /~~/, $d;
                LIMS::DB::LabSectionStatusOption->new(
                    status_option_id => $option_id,
                    lab_section_id   => $data->{section_id},
                    position         => $position,
                )->save;
            }
        }
        elsif ($option_data) { # need to test in case it's a submit to clear
            my ($option_id, $position) = split /~~/, $option_data;
            LIMS::DB::LabSectionStatusOption->new(
                status_option_id => $option_id,
                lab_section_id   => $data->{section_id},
                position         => $position,
            )->save;
        }
    };

    my $ok = $db->do_transaction($update);

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

#-------------------------------------------------------------------------------
sub update_lab_sections {
    my $self = shift;
    my $data = shift; # warn Dumper $data; return 1;

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

    # get lab_section data from $data - will be same thing if sample_type_id not used:
    my %lab_section_data = map {
        $_ => $data->{$_};
    } grep $_ ne 'sample_type_id', keys %$data; # warn Dumper \%lab_section_data;

    my $update = sub {
        my %args = ( class => 'LabSection', data => \%lab_section_data );
        $self->update_object(\%args);

        # sample_type_id data if configured:
        if ( my $sample_type_id = $data->{sample_type_id} ) {
            # $sample_type_id will be str if singular, or arrayref if multiple:
            $sample_type_id = [ $sample_type_id ]
                unless ref $sample_type_id eq 'ARRAY';

            my $lab_section_id = $data->{_record_id}; # only if not new entry

            if ($lab_section_id) { # not new lab_section so clear existing data:
                LIMS::DB::LabSectionSampleType::Manager->delete_lab_section_sample_types(
                    where => [ lab_section_id => $lab_section_id ],
                );
            }
            else { # get new lab_section id:
                my $dbh = $self->lims_db->dbh;
                $lab_section_id
                    = $dbh->last_insert_id(undef, undef, 'lab_sections', 'id');
            }

            my %data = ( lab_section_id => $lab_section_id );
            map {
                $data{sample_type_id} = $_;
                LIMS::DB::LabSectionSampleType->new(%data)->save;
            } @$sample_type_id;
        }
    };

    my $ok = $db->do_transaction($update);

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

#-------------------------------------------------------------------------------
sub get_section_result_summaries {
    my ($self, $request_id, $section_name) = @_; # $section_name optional

    my @query = ( request_id => $request_id );
    push @query, ( section_name => $section_name ) if $section_name;
    
    my %args = (
        query           => \@query,
        require_objects => ['lab_section','user'],
    );

    my $result_summaries = LIMS::DB::RequestResultSummary::Manager
        ->get_request_result_summaries(%args);

    return $result_summaries;
}

1;
