#!/usr/bin/perl

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

use Data::Dumper;

use strict;
use warnings;

use Test::More tests => 127; #   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; add secondary diagnosis
9) complete outstanding tests & enter final diagnosis
10) unlock record
11) change comment, gross_description & secondary diagnosis - check for text highlights
12) change comment again - check for text highlights
13) delete secondary diagnosis
=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 (fresh tissue) with no lab tests:
	my $dbix = get_dbix();
    $dbix->insert('screens', { description => 'morphology', category_id => 1 });
    # new option: teaching
	$dbix->insert('additional_options',
		{ option_name => 'teaching', option_label => 'Teaching'});
	# for secondary diagnosis:
	$dbix->insert('diagnoses', { name => 'ITP', diagnostic_category_id => 3 });
}

# 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();
    # now a j/s function so have to submit manually:
    $mech->get_ok('/screen/do_initial_screen/1?screen_id=3;option_id=1'); # print_and_exit();

    $mech->text_contains(
        'Screened as morphology',
        'OK: expected screen term found',
    );                                                       # print_and_exit();

    $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',
        gross_description => 'gross description here',
        specimen_quality => 'adequate',
        diagnosis_id => 1,
    );

    test_missing_required(\%report, 'reportForm');            # print_and_exit();

    # add some optional fields:
    $report{clinical_details} = 'some details here';
    $report{comment} = 'comment here';
    $report{morphology} = 'morphology here';

    $mech->form_name('reportForm');
	# add teaching option:
	$mech->field(teaching => 1);
    $mech->submit_form(fields => \%report);                   # print_and_exit();

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

    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->text_contains(
        'Quality: ' . $report{specimen_quality},
        'OK: expected text found',
    );                                                        # print_and_exit();
    $mech->text_contains(
        'Diagnosis: RAEB',
        'OK: expected diagnosis found',
    );                                                        # print_and_exit();

    $mech->get_ok('/history/=/1');                            # print_and_exit();
    for ('new teaching option','reported' ) {
		$mech->has_tag(
			td => $_,
			'OK: expected history found',
		);
	} 														# print_and_exit();
}

{ # self authorise (not allowed, but CAN now edit own report):
    $mech->back();

    # should have 'Report' link ie not Authorise - allows editing of own report:
    $mech->follow_link_ok(
        { url_regex => qr/report/i, },
        'follow "report" link',
    );                                                       #  print_and_exit();
    SKIP: {
        skip('now allowing own report edit',1);
        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',
    );

    $mech->form_name('reportForm');
    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->form_name('reportForm');
    $mech->field(option_id => 2); # 'update'

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

    lacks_dfv_errors();                                       # 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->text_like(
        qr(Diagnosis:\s+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();

	# test for bugfix for inappropriate deletion of teaching opt:
	test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag_like( td => 'delete option teaching', 'foo' );
    test_test( 'OK: teaching option NOT deleted' );

    # 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->form_name('reportForm');
    $mech->field( diagnosis_id => 1 );
    $mech->submit_form();                                      # 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->form_name('reportForm');
    $mech->field( diagnosis_id => 1 );
    $mech->submit_form();                                     # 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->form_name('reportForm');
	# remove teaching option:
	$mech->set_fields('teaching' => 0);

    $mech->field( authorise => 1 );
    $mech->submit_form();                                    # 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();
    }

    $mech->text_contains(
        'Reported by First_name Last_name', # default details of changed user
        'OK: expected reporter details found',
    );                                                        # print_and_exit();

    $mech->text_contains(
        '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 [1]',
    );                                                        # print_and_exit();
    $mech->has_tag(
        td => 'delete option teaching',
        'OK: expected history found [2]',
    );                                                        # print_and_exit();
}

# screen request so it can be reported:
$mech->get_ok('/screen/=/2');                                 # print_and_exit();
{
    $mech->form_name('initialScreen'); # 1st one is patient notes

    $mech->field(screen_id => 1); # allocates tests:
    $mech->field(option_id => 1);
    $mech->submit();                                          # print_and_exit();

    $mech->text_contains(
        '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->content_contains(
        '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 => 'comment here',
        specimen_quality => 'adequate',
        diagnosis_id => 2,
    );

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

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

	# specimen = LU so needs biopsy_site:
    has_dfv_errors();
    has_missing();                                            # print_and_exit();

    $mech->form_name('reportForm');
    $mech->field( biopsy_site => 'lymph node' );
    $mech->submit_form();                                    #  print_and_exit();
    $mech->submit_form(form_name => 'reportForm') if $spell_check_required;

    lacks_dfv_errors();                                       # print_and_exit();

    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->form_name('reportForm');
    $mech->field( confirm_outstanding_tests => 1 );
    $mech->field( diagnosis_id => 1 );
    $mech->field( authorise => 1 );
    $mech->submit_form();                                     # 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->form_name('reportForm');
    $mech->field( option_id => 1 );   # 'error'
    $mech->field( authorise => 1 );
	# amend biopsy_site:
	$mech->field( biopsy_site => 'peripheral blood');
	# add secondary diagnosis same as primary (not allowed):
	$mech->field( secondary_diagnosis_id => 1 ); #
    $mech->submit_form();                                     # print_and_exit();
    has_dfv_errors();
    $mech->has_tag_like(
    	span => get_dfv_message('duplicate_diagnosis'),
    	'OK: expected error message found',
    );

    # change secondary_diagnosis:
    $mech->form_name('reportForm');
    $mech->field( secondary_diagnosis_id => 3 ); # ITP
    $mech->submit_form();                                      # print_and_exit();
    $mech->submit_form(form_name => 'reportForm') if $spell_check_required;
    lacks_dfv_errors();                                        # 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->text_contains(
        'Authorised by Admin_fname Admin_lname',
        'OK: expected authoriser details found',
    );                                                        # print_and_exit();

    # check diagnosis correct:
    $mech->text_like(
        qr(Diagnosis:\s+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' );

    # check secondary diagnosis correct:
    $mech->text_like(
        qr(Secondary diagnosis:\s+ITP),
        'OK: secondary diagnosis found',
    );                                                        # print_and_exit();
}

# check history:
$mech->get_ok('/history/=/2');								  # print_and_exit();
{
	my $i = 0;
	for ( 'diagnosis', 'biopsy site' ) { $i++;
        $mech->has_tag_like(
            td => qr(amended $_),
            "OK: expected history found [$i]",
        );
	}														# print_and_exit();
}

# 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_form(form_name => 'reportForm') if $spell_check_required;

    # should have 'confirm final diagnosis' checkbox now:
    $mech->has_tag_like(
        div => qr(CONFIRM FINAL DIAGNOSIS),
        'OK: confirm final diagnosis checkbox found',
    );                                                        # print_and_exit();

    $mech->form_name('reportForm');
    $mech->field(final_diagnosis => 1);
    $mech->submit_form();                                    # 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 & secondary diagnosis:
{
    # 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 = 'comment changed here';
    my $gross_desc = 'gross description changed here';
    $mech->form_name('reportForm');
    $mech->field( comment => $comment );
    $mech->field( gross_description => $gross_desc );
	is( $mech->field('secondary_diagnosis_id'), 3,
	   'OK: expected secondary diagnosis id found' );
	# change it:
	$mech->field( secondary_diagnosis_id => 2 ); # CLL
    $mech->submit_form();                                     # 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();

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

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

	# check secondary diagnosis correct:
    $mech->text_like(
        qr(Secondary diagnosis:\s+CLL),
        'OK: secondary diagnosis found',
    );                                                        # print_and_exit();

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

    {
        my $i = 0;
        for ( 'comment', 'gross description', 'secondary diagnosis' ) { $i++;
            $mech->has_tag_like( # comment has 'view' link
                td => qr(amended $_),
                "OK: expected history found [$i]",
            );
        }                                                     # 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 = 'comment changed';

    $mech->form_name('reportForm');
    $mech->field( comment => $comment );
	# delete secondary diagnosis:
	$mech->tick( delete_secondary_diagnosis => 1 );

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

    # jump straight to view comment history:
    $mech->get_ok('/history/report_diff/2/comment');         # print_and_exit();

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

	$mech->get_ok('/report/=/2');                             #  print_and_exit();
	is( $mech->field('secondary_diagnosis_id'), '',
	   'OK: secondary diagnosis id null' );

	$mech->get_ok('/history/=/2');                            #  print_and_exit();
	$mech->has_tag_like( # comment has 'view' link
        td => qr(deleted secondary diagnosis),
        'OK: expected history found',
    );
}
