#!/usr/bin/perl

use Test::WWW::Mechanize::CGIApp;
use Test::Builder::Tester;

use Data::Dumper;

use strict;
use warnings;

use constant TESTS => 76;

use Test::More tests => TESTS; 
# use Test::More 'no_plan';

# tests rules for requiring diagnosis confirmation at report stage:

=begin: tests:
all tests performed on a request with a molecular results summary:

1) request with exempt screen (PNH)
2) request with exempt screen if specimen type (CML interferon follow-up) + LU
3) request with exempt screen if specimen type (CML interferon follow-up) + PB
4) request with exempt screen if specimen type & test (CMPD pres & follow-up) + PB + JAK2 + CML 
5) request with exempt screen if specimen type & test (CMPD pres & follow-up) + PB + BMAT + JAK2 
6) request with exempt screen if specimen type & test (CMPD pres & follow-up) + PB JAK2 
=cut

BEGIN {
    require 't/test-lib.pl';
}

my $dbh;

eval {
    $dbh = get_dbh() or die 'no database handle recieved from get_dbh';
};

warn $@ if $@;

# vars needed if tests are run:
use vars qw($mech $dbix $spell_check_required);

my $yaml = get_yaml('diagnosis_confirm'); # warn Dumper $yaml;

if ($yaml) {
    $mech = get_mech();
    $dbix = get_dbix();

    # need to see if 'require_spell_check' is required:
    $spell_check_required = is_spell_check_required(); # warn $spell_check_required;
}

SKIP: {
    skip('these tests require config/.local/settings/diagnosis_confirm.yml file',TESTS) unless $yaml;
    do_all_tests();
}

sub do_all_tests {

    do_login();

# register some new data (fresh tissue):
{   # new screen term which requires a final_diagnosis check:    
    $dbix->insert('screens',
        { description => 'CML interferon follow-up', category_id => 1 }
    );
    # new screen term which doesn't require a final_diagnosis check (if PB & jak2):    
    $dbix->insert('screens',
        { description => 'CMPD pres & follow-up', category_id => 1 }
    );
    $dbix->insert( 'lab_tests',
        { test_name => 'jak2', field_label => 'JAK2', lab_section_id => 3,
            test_type => 'test', has_results => 'no' }
    );
    # new screen terms requests molecular lab_tests:
    $dbix->insert('screen_lab_test',
        { screen_id => 3, lab_test_id => 5 } # APML - is a Molecular test
    );
    $dbix->insert('screen_lab_test',
        { screen_id => 4, lab_test_id => 10 } # JAK2 - is a Molecular test
    );
    # new user to change reporter so can authorise:
    $dbix->insert('users', { username => 'user1' }); # only required field
    # change Flow lab_section 'has_test_sign_out' value:
    $dbix->update( 'lab_sections',
        { has_test_sign_out => 'yes' }, { section_name => 'Flow' }
    );
}

# 1) PNH exempt from final_diagnosis confirmation:
# screen request:
$mech->get_ok('/screen/=/1');                                 # print_and_exit();
{
    _do_screen(2,'PNH');                                      # print_and_exit();
}

# sign off result:
$mech->get_ok('/result/=/1');                                 # print_and_exit();
{
    _do_results_sign_off('flow_results');                     # print_and_exit();
}

# report & authorise record:
$mech->get_ok('/report/=/1');                                 # print_and_exit();
{
    _do_report(1);                                           #  print_and_exit();    
}

# should be status = complete:
is( _get_status_option(1), 5, 'OK: expected request status found' ); # print_and_exit(); 
#-------------------------------------------------------------------------------

# 2) CML interferon follow-up on LU sample - requires comfirmation:
# screen request so it can be reported:
$mech->get_ok('/screen/=/2');                                 # print_and_exit();
{
    _do_screen(3,'CML interferon follow-up');                 # print_and_exit();
}

# sign off result & enter result summary:
$mech->get_ok('/result/=/2');                                 # print_and_exit();
{
    _do_results_summary();                                    # print_and_exit();
}

# report record:
$mech->get_ok('/report/=/2');                                 # print_and_exit();
{
    _do_report(2);                                            # print_and_exit();    
}
    
# should NOT be status = complete:
is( _get_status_option(2), 4, 'OK: expected request status found' ); # print_and_exit(); 

# re-report and check final_diagnosis box:
$mech->get_ok('/report/=/2');                                 # print_and_exit();
{
    _do_re_report(2);                                         # print_and_exit();    
}
    
# should now be status = complete:
is( _get_status_option(2), 5, 'OK: expected request status found' ); # print_and_exit(); 
#-------------------------------------------------------------------------------

# 3) CML interferon follow-up on PB - exempt from confirmation:
_register_new_request(3);
$mech->get_ok('/screen/=/3');                                 # print_and_exit();
{
    _do_screen(3,'CML interferon follow-up');                 # print_and_exit();
}

# sign off result & enter result summary:
$mech->get_ok('/result/=/3');                                 # print_and_exit();
{
    _do_results_summary();                                    # print_and_exit();
}

# report record:
$mech->get_ok('/report/=/3');                                 # print_and_exit();
{
    _do_report(3);                                            # print_and_exit();    
}

# should be status = complete:
is( _get_status_option(3), 5, 'OK: expected request status found' ); # print_and_exit(); 
#-------------------------------------------------------------------------------

# 4) CMPD pres & follow-up on PB with JAK2 + CML tests - requires confirmation:
_register_new_request(4);
$mech->get_ok('/screen/=/4');                                 # print_and_exit();
{
    _do_screen(4,'CMPD pres & follow-up');                    # print_and_exit();
}
# request new lab_test and sign it off:
$mech->get_ok('/result/=/4');                                 # print_and_exit();
{
    $mech->form_name('flow_requests');
    $mech->tick('test_id', 2, 1);
    $mech->submit();                                          # print_and_exit();
    
    $mech->get_ok('/result/=/4');                             # print_and_exit();
    _do_results_sign_off('flow_results');                     # print_and_exit();
}

# sign off result & enter result summary:
$mech->get_ok('/result/=/4');                                 # print_and_exit();
{
    _do_results_summary();                                    # print_and_exit();
}

# report record:
$mech->get_ok('/report/=/4');                                 # print_and_exit();
{
    _do_report(4);                                            # print_and_exit();    
}

# should NOT be status = complete:
is( _get_status_option(4), 4, 'OK: expected request status found' ); # print_and_exit();

# re-report and check final_diagnosis box:
$mech->get_ok('/report/=/4');                                 # print_and_exit();
{
    _do_re_report(4);                                         # print_and_exit();    
}
    
# should now be status = complete:
is( _get_status_option(4), 5, 'OK: expected request status found' ); # print_and_exit(); 

#-------------------------------------------------------------------------------

# 5) CMPD pres & follow-up on PB & BMAT with JAK2 - requires confirmation:
_register_new_request(5, 'pb,bmat');
$mech->get_ok('/screen/=/5');                                 # print_and_exit();
{
    _do_screen(4,'CMPD pres & follow-up');                    # print_and_exit();
}

# sign off result & enter result summary:
$mech->get_ok('/result/=/5');                                 # print_and_exit();
{
    _do_results_summary();                                    # print_and_exit();
    
    # BMAT requests AUTO (histology) test:
    $mech->get_ok('/result/=/5');                             # print_and_exit();
    _do_results_sign_off('histology_results');                # print_and_exit();
}

# report record:
$mech->get_ok('/report/=/5');                                 # print_and_exit();
{
    _do_report(5);                                            # print_and_exit();    
}

# should NOT be status = complete:
is( _get_status_option(5), 4, 'OK: expected request status found' ); # print_and_exit();

# re-report and check final_diagnosis box:
$mech->get_ok('/report/=/5');                                 # print_and_exit();
{
    _do_re_report(5);                                         # print_and_exit();    
}
    
# should now be status = complete:
is( _get_status_option(5), 5, 'OK: expected request status found' ); # print_and_exit(); 

#-------------------------------------------------------------------------------

# 5) CMPD pres & follow-up on PB with JAK2 only - exempt from confirmation:
_register_new_request(6);
$mech->get_ok('/screen/=/6');                                 # print_and_exit();
{
    _do_screen(4,'CMPD pres & follow-up');                    # print_and_exit();
}

# sign off result & enter result summary:
$mech->get_ok('/result/=/6');                                 # print_and_exit();
{
    _do_results_summary();                                    # print_and_exit();
}

# report record:
$mech->get_ok('/report/=/6');                                 # print_and_exit();
{
    _do_report(6);                                            # print_and_exit();    
}

# should be status = complete:
is( _get_status_option(6), 5, 'OK: expected request status found' ); # print_and_exit();
}

sub _register_new_request {
    my $request_number = shift;
    my $specimen = shift || 'pb';
    
    $mech->get_ok('/request/add_new/2');                      # print_and_exit();
    
    $mech->submit_form(
        fields => {
            request_number => $request_number,
            referrer_code => 'C9999998',
            specimen => $specimen,
        }
    );                                                        # print_and_exit();
} 

sub _get_status_option {
    my $id = shift;
    
    my $status_option_id = $dbix->query(
        q!select status_option_id from requests where id = ?!, $id
    )->list;
        
    return $status_option_id;
}

sub _do_screen {
    my ($screen_id, $screen) = @_;
    
    $mech->field(screen_id => $screen_id);
    $mech->field(option_id => 1);
    $mech->submit(); 
    
    $mech->has_tag_like(
        p => qr(Screened as $screen),
        'OK: expected screen term found',
    );
}

sub _do_results_summary {
    my $text = 'molecular result summary';
    
    $mech->form_name('molecular_results');
    $mech->field(results_summary => $text);
    $mech->tick('complete_all_tests', 1, 1);
    
    $mech->submit();                                        
    
    $mech->has_tag_like(
        td => qr($text),
        'OK: expected text found',
    );    
}

sub _do_results_sign_off {
    my $form_name = shift;
    
    $mech->form_name($form_name);
    $mech->tick('complete_all_tests', 1, 1);
    
    $mech->submit(); 
}

sub _do_report {
    my $id = shift;
    
    my $report = _get_report();
    
    $mech->form_name('reportForm');
    $mech->submit_form(fields => $report);                    # print_and_exit();
    $mech->submit_form(form_name => 'reportForm') if $spell_check_required;

    my $msg = get_messages('action')->{edit_success};
    $mech->has_tag_like(
        p => qr($msg),
        'OK: record updated successfully',
    );                                            # print_and_exit() if $id == 5;

    # have to manually change reporter ID or self-auth refused:
    $dbix->update(
        'request_history',
        { user_id => 2 }, 
        { request_id => $id, action => 'reported' }
    );
    
    # skip pre-auth check:
    $mech->get_ok("/report/=/$id?pre-authorisation-check=1"); # print_and_exit();

    $mech->form_name('reportForm');
    $mech->field( authorise => 1 );
    $mech->submit_form();                                          # print_and_exit();
    $mech->submit_form(form_name => 'reportForm') if $spell_check_required;

    $mech->has_tag_like(
        p => qr($msg),
        'OK: record updated successfully',
    );                                                        # print_and_exit();
    
    $mech->has_tag_like(
        p => qr(Authorised by Admin_fname Admin_lname),
        'OK: expected authoriser details found',
    );
}

sub _do_re_report {
    my $id = shift;
    
    $mech->form_name('reportForm');
    $mech->tick('final_diagnosis', 1, 1);                     
    $mech->submit_form();                                          # print_and_exit();
    $mech->submit_form(form_name => 'reportForm') if $spell_check_required;
}

sub _get_report {
    return {
        status  => 'default',
        clinical_details => 'some details here',
        gross_description => 'gross description here',
        comment => 'morphology comment here',
        specimen_quality => 'adequate',
        diagnosis_id => 1,
    };
}