#!/usr/bin/perl

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

use Data::Dumper;

use strict;
use warnings;

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

=begin: tests:
1) try to report unscreened record
2) test_missing_required fields
3) self authorise (not allowed)
4) try to change diagnosis (forget required field 'revision') at report stage
5) try to change diagnosis without revision reason at authorisation stage
6) authorise report
7) try to submit report with outstanding tests & without acknowledgment
8) try to authorise and change diagnosis without reason
9) complete outstanding tests & enter final diagnosis
10) unlock record
11) change comment & gross_description - check for text highlights
12) change comment again - check for text highlights
=cut

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

my $mech = get_mech();

do_login();

my $dbh;

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

warn $@ if $@;

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

# new screen term with no lab tests:
{
    my $dbix = get_dbix();

    $dbix->insert('screens', { description => 'morphology', sample_type => 'fresh' });
}

# try to report unscreened record:
$mech->get_ok('/report/=/1');                                 # print_and_exit();
{
    my $msg = get_messages('report')->{not_screened};
    $mech->has_tag_like(        
        p => qr($msg),
        'OK: expected error message found',
    );                                                        # print_and_exit();
}

# screen request so it can be reported:
$mech->get_ok('/screen/=/1');                                 # print_and_exit();
{
    $mech->field(screen_id => 3);
    $mech->field(option_id => 1);
    $mech->submit();                                          # print_and_exit();
    
    $mech->has_tag_like(
        p => qr(Screened as morphology),
        'OK: expected screen term found',
    );
    
    $mech->follow_link_ok(
        # {n => 8}, "Logout $_ via eighth link on page",
        { url_regex => qr/report/i, },
        'follow "report" link',
    );                                                        # print_and_exit();
    
    # test missing:
    my %report = (
        status  => 'default',
        clinical_details => 'some details here',
        gross_description => 'gross description here',
        comment => 'morphology comment here',
        specimen_quality => 'adequate',
        diagnosis_id => 1,
    );
    
    test_missing_required(\%report);                         # print_and_exit();

    $mech->submit_form(fields => \%report);                  # print_and_exit();
    $mech->submit() if $spell_check_required;                # print_and_exit();
    lacks_dfv_errors();
    
    my $msg = get_messages('action')->{edit_success};
    $mech->has_tag_like(
        p => qr($msg),
        'OK: record updated successfully',
    );                                                        # print_and_exit();
    
    foreach (@report{qw(clinical_details comment)}) {
        $mech->has_tag(
            td => $_,
            'OK: expected text found',
        );
    }
    $mech->has_tag_like(
        td => qr(Quality: $report{specimen_quality}),
        'OK: expected text found',
    );                                                        # print_and_exit();
    $mech->has_tag(
        td => 'RAEB',
        'OK: expected diagnosis found',
    );                                                        # print_and_exit();
    
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    $mech->has_tag(
        td => 'reported',
        'OK: expected history found',
    );                                                        # print_and_exit();
}

{ # self authorise (not allowed):
    $mech->back();
    
    # should have 'Authorise' link:
    $mech->follow_link_ok(
        { url_regex => qr/authorise/i, },
        'follow "authorise" link',
    );                                                        # print_and_exit();
    
    my $msg = get_messages('report')->{no_self_auth};
    $mech->has_tag_like(
        p => qr($msg),
        'OK: self-authorisation not allowed',
    );
}

{ # inactivate 'authorise' & change diagnosis:
    $mech->get_ok('/config/status-options/edit/4');           # print_and_exit();
    
    #$mech->field(description => 'authorise');
    $mech->field(is_active => 'no');
    $mech->submit();                                          # print_and_exit();
 
    SKIP: { skip("field is diabled so doesn't report content", 1);
        is( $mech->field('active', 1), 'no', 'OK: option inactive');
    }
    $mech->get_ok('/report/=/1');                             # print_and_exit();
    
    # no previous matches:
    $mech->has_tag(
        p => 'No previous patient matches found',
        'OK: no previous matches found',
    );
    
    is( $mech->field('diagnosis_id', 1), 1, 'OK: expected diagnosis loaded');
    
    # change diagnosis (forget revision):
    $mech->field(diagnosis_id => 2);
    $mech->submit();                                          # print_and_exit();
    
    has_dfv_errors();                                       
    $mech->has_tag_like(
    	span => get_dfv_message('report_confirm'),
    	'OK: expected error message found',
    );                                             			 #  print_and_exit();

    $mech->field(revision => 'update');
    $mech->submit();                                          # print_and_exit();
    $mech->submit() if $spell_check_required;                 # print_and_exit();

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

    $mech->has_tag_like(
        td => qr(CLL), 
        'OK: changed diagnosis found',
    );                                                        # print_and_exit();
    test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag_like( td => qr(RAEB), 'foo' );
    test_test( 'OK: original diagnosis not found' );

    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag(
        td => 'amended diagnosis (update)',
        'OK: expected history found (1)',
    );                                                        # print_and_exit();
    $mech->has_tag_like(
        h3 => 'Diagnosis history',
        'OK: expected history found (2)',
    );                                                        # print_and_exit();

    # has link to previous diagnosis:
    $mech->get_ok('/search/=/1');                             # print_and_exit();

    $mech->follow_link_ok(
        { url_regex => qr(history/previous_diagnosis/1), },
        'follow "previous diagnosis" link',
    );                                                        # print_and_exit();
    
    $mech->has_tag_like(
        h4 => qr/Previous diagnoses for (\w)1/, # ie H1, D1, etc
        'OK: expected heading found',
    );                                                        # print_and_exit();
    $mech->has_tag(
        td => 'RAEB',
        'OK: old diagnosis history found',
    );                                                        # print_and_exit();    
}

# re-enable 'authorise', manually change reporter to new user, do authorisation:
{
    my $dbix = get_dbix();
    $dbix->update( 'status_options', { is_active => 'yes' }, { id => 4 } );
    $dbix->insert( 'users', { username => 'user1', group_id => 1 } ); # rest = default
    $dbix->update( 'request_history', { user_id => 2 }, { action => 'reported' } );
    # reset status_option_id from 'complete' or nav links unavailable:
    $dbix->update( 'requests', { status_option_id => 3 }, { id => 1 } );
    
    $mech->get_ok('/search/=/1');                             # print_and_exit();
    # should have 'Authorise' link:
    $mech->follow_link_ok(
        { url_regex => qr/authorise/i, },
        'follow "authorise" link',
    );                                                        # print_and_exit();
    $mech->field( diagnosis_id => 1 );
    $mech->submit();                                          # print_and_exit();
    
    $mech->has_tag_like(
        h3 => qr(Pre-authorisation check),
        'OK: expected page title',
    );
    
    # should have detected different diagnoses:
    $mech->has_tag_like(
        td => qr(CLL), 
        'OK: original diagnosis detected'
    );
    $mech->has_tag_like(
        span => qr(RAEB), # highlighted in red
        'OK: different diagnosis detected'
    );                                                        # print_and_exit();
    
    $mech->follow_link_ok(
        { url_regex => qr(pre-authorisation-check), },
        'follow "continue" link',
    );                                                        # print_and_exit();
    
    # try to change diagnosis without revision reason:
    $mech->field( diagnosis_id => 1 );
    $mech->submit();                                          # print_and_exit();

    has_dfv_errors();                                       
    {
        my $msg = get_dfv_message('report_confirm');    
        $mech->has_tag_like(
            span => qr($msg),
            'OK: required field missing',
        );                                                    # print_and_exit();
    }
    
    $mech->back();
    $mech->field( authorise => 1 );
    $mech->submit();                                          # print_and_exit();
    $mech->submit() if $spell_check_required;                 # print_and_exit();
    
    {
        my $msg = get_messages('action')->{edit_success};
        $mech->has_tag_like(
            p => qr($msg),
            'OK: record updated successfully',
        );                                                    # print_and_exit();
    }
    
    $mech->has_tag_like(
        p => qr(Reported by First_name Last_name), # default details of changed user
        'OK: expected reporter details found',
    );                                                        # print_and_exit();
    
    $mech->has_tag_like(
        p => qr(Authorised by Admin_fname Admin_lname), 
        'OK: expected authoriser details found',
    );                                                        # print_and_exit();
    
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    $mech->has_tag(
        td => 'authorised',
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# screen request so it can be reported:
$mech->get_ok('/screen/=/2');                                 # print_and_exit();
{
    $mech->field(screen_id => 1); # allocates tests:
    $mech->field(option_id => 1);
    $mech->submit();                                          # print_and_exit();
    
    $mech->has_tag_like(
        p => qr(Screened as AML),
        'OK: expected screen term found',
    );
    
    $mech->follow_link_ok(
        # {n => 8}, "Logout $_ via eighth link on page",
        { url_regex => qr/report/i, },
        'follow "report" link',
    );                                                        # print_and_exit();
    
    $mech->has_tag_like(
        span => qr(outstanding tests),
        'OK: outstanding tests warning found',
    );                                                        # print_and_exit();
 
    $mech->has_tag(
        span => 'ACKNOWLEDGE OUTSTANDING TESTS:',
        'OK: outstanding tests acknowledgment found',
    );                                                        # print_and_exit();
    
    # check it doesn't have 'confirm final diagnosis' checkbox:
    test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag_like( span => qr(CONFIRM FINAL DIAGNOSIS), 'foo' );
    test_test( 'OK: confirm final diagnosis checkbox absent' );      
    
    # try to submit without outstanding tests acknowledgment:
    my %report = (
        status  => 'default',
        clinical_details => 'some details here',
        gross_description => 'gross description here',
        comment => 'morphology comment here',
        specimen_quality => 'adequate',
        diagnosis_id => 2,
    );

    $mech->submit_form(fields => \%report);                   # print_and_exit();
    has_dfv_errors();                                       
    has_missing();                                       

    $mech->field( confirm_outstanding => 1 );
    $mech->submit();                                          # print_and_exit();
    $mech->submit() if $spell_check_required;                 # print_and_exit();
    
    lacks_dfv_errors();
    
    my $msg = get_messages('action')->{edit_success};
    $mech->has_tag_like(
        p => qr($msg),
        'OK: record updated successfully',
    );                                                        # print_and_exit();   
}

# jump straight to authorisation:
$mech->get_ok('/report/=/2?pre-authorisation-check=1');       # print_and_exit();
{
    # self-authorisation not permitted:
    $mech->has_tag_like(
        span => qr(self-authorisation not permitted),
        'OK: self-authorisation not allowed',
    );

    # manually change reporter's id:
    my $dbix = get_dbix();
    $dbix->update( 'request_history',
        { user_id => 2 }, { action => 'reported', request_id => 2 },
    );
    
    $mech->get_ok('/report/=/2?pre-authorisation-check=1');   # print_and_exit();
    test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag_like( span => qr(self-authorisation not permitted), 'foo' ); 
    test_test( 'OK: no self-authorisation disallowed notice' );      
    
    # try to authorise and change diagnosis without reason:
    $mech->field( confirm_outstanding => 1 );
    $mech->field( diagnosis_id => 1 );
    $mech->field( authorise => 1 );    
    $mech->submit();                                          # print_and_exit();
    
    has_dfv_errors();
    $mech->has_tag_like(
    	span => get_dfv_message('report_confirm'),
    	'OK: expected error message found',
    );                                             			  # print_and_exit();
    
    # supply reason:
    $mech->field( revision => 'error' );    
    $mech->field( authorise => 1 );    
    $mech->submit();                                          # print_and_exit();
    $mech->submit() if $spell_check_required;                 # print_and_exit();

    lacks_dfv_errors();
    
    {
        my $msg = get_messages('action')->{edit_success};
        $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',
    );                                                        # print_and_exit();
    
    # check diagnosis correct:
    $mech->has_tag_like(
        td => qr(RAEB), 
        'OK: changed diagnosis found',
    );                                                        # print_and_exit();
    test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag_like( td => qr(CLL), 'foo' );
    test_test( 'OK: original diagnosis not found' );    
}

# complete outstanding tests & enter final diagnosis:
{
    $mech->get_ok('/worklist/display/1?display_format=Data+Entry');
    $mech->field(status_option_id => 2);
    $mech->field(request_lab_test_id => 1);
    $mech->submit();                                          # print_and_exit();
    
    $mech->get_ok('/worklist/display/3?display_format=Data+Entry');
    $mech->field(status_option_id => 2);
    $mech->field(request_lab_test_id => 2);
    $mech->submit();                                          # print_and_exit();
    
    $mech->get_ok('/report/=/2');                             # print_and_exit();
    $mech->submit() if $spell_check_required;                #  print_and_exit();
    
    # should have 'confirm final diagnosis' checkbox now:
    $mech->has_tag_like(
        span => qr(CONFIRM FINAL DIAGNOSIS), 
        'OK: confirm final diagnosis checkbox found',
    );                                                        # print_and_exit();

    $mech->field(final_diagnosis => 1);
    $mech->submit();                                          # print_and_exit();
    
    lacks_dfv_errors();
    
    {
        my $msg = get_messages('action')->{edit_success};
        $mech->has_tag_like(
            p => qr($msg),
            'OK: record updated successfully',
        );                                                    # print_and_exit();
    }
}

# change updated_at so record is locked:
{
    my $dbix = get_dbix();
    my $yesterday = DateTime->now->subtract(days => 1);
    $dbix->update( 'requests',
        { updated_at => $yesterday }, { request_number => 2 },
    );

    $mech->get_ok('/search/=/2');                             # print_and_exit();

    # should make record complete & remove 'edit' links:
    $mech->content_contains(
        'locked_small.png', # has 'unlocked.png' if not locked
        'OK: record locked image found',
    );                                                        # print_and_exit();

    # try to jump straight to report page:
    $mech->get_ok('/report/=/2');                             # print_and_exit();
    # should have 'record search' title:
    $mech->has_tag_like(
        p => qr(Record Search),
        'OK: direct access to report page disallowed',
    );
    
    # unlock record:
    $mech->follow_link_ok(
        # {n => 8}, "Logout $_ via eighth link on page",
        { url_regex => qr/unlock_request/i, },
        'OK: has working "unlock_request" link',
    );                                                        # print_and_exit();
    
    $mech->has_tag_like(
        p => qr(Confirm you want to unlock this record), 
        'OK: unlock record checkbox found',
    );                                                        # print_and_exit();

    $mech->field(confirm_unlock => 1);
    $mech->submit();                                          # print_and_exit();
    
    $mech->has_tag_like(
        p => qr(record unlocked),
        'OK: record unlocked successfully',
    );
    
    # test_out never fails here - WTF???
#    test_out( 'not ok 1 - foo' );
#    test_fail( +1 );
#    $mech->content_contains( 'locked_small.png', 'foo' );
#    $mech->has_tag_like( td => qr(NO_SUCH_TEXT_HERE), 'foo' ); # still passes !!
#    test_test( 'OK: record locked image absent' );      

    # have active Report & Result links back:
    my @links = $mech->find_all_links( url_regex => qr/result|report/ );
    $mech->links_ok( \@links, 'OK: active Report & Result links checked' );
}

# change comment & gross_description:
{
    # check history terms not present:
    $mech->get_ok('/history/=/2');                             # print_and_exit();
    for ( 'comment', 'gross description' ) {
        test_out( 'not ok 1 - foo' );
        test_fail( +1 );
        $mech->has_tag( td => "amended $_", 'foo' ); 
        test_test( 'OK: expected history absent' );      
    }

    $mech->get_ok('/report/=/2');                             # print_and_exit();

    my $comment = 'morphology comment changed here';
    my $gross_desc = 'gross description changed here';
    
    $mech->field( comment => $comment );
    $mech->field( gross_description => $gross_desc );
    $mech->submit();                                          # print_and_exit();
    $mech->submit() if $spell_check_required;                 # print_and_exit();

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

    $mech->has_tag(
        td => $comment,
        'OK: expected text found [1]',
    );

    $mech->has_tag_like( # need '_like' - part of td with specimen quality
        td => $gross_desc,
        'OK: expected text found [2]',
    );                                                        # print_and_exit();

    $mech->get_ok('/history/=/2');                            # print_and_exit();
    
    for ( 'comment', 'gross description' ) {
        $mech->has_tag_like( # comment has 'view' link 
            td => qr(amended $_),
            'OK: expected history found',
        );
    }                                                         # print_and_exit();
    
    # should be able to follow 'view' link:
    $mech->follow_link_ok(
        # {n => 8}, "Logout $_ via eighth link on page",
        { url_regex => qr/comment/i, },
        'follow "view" link',
    );                                                        # print_and_exit();
    
    # check text addition detected:
    $mech->content_contains(
        q!<span class="add">changed</span>!,
        'OK: added content highlighted',        
    );    
}

# change comment again - check for deletion:
$mech->get_ok('/report/=/2');                                 # print_and_exit();
{
    my $comment = 'morphology comment changed';
    
    $mech->field( comment => $comment );
    $mech->submit();                                          # print_and_exit();
    $mech->submit() if $spell_check_required;                 # print_and_exit();
    
    # jump straight to view commeny history:
    $mech->get_ok('/history/comment/2');                      # print_and_exit();

    # check text deletion detected:
    $mech->content_contains(
        q!<span class="del">here</span>!,
        'OK: deleted content highlighted',        
    );                                                        # print_and_exit();
}
