#!/usr/bin/perl

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

use strict;
use warnings;

use POSIX;

use Test::More tests => 144;
# use Test::More 'no_plan';
 
=begin # tests:
1) change referrer to another clinician
2) change referrer to unknown
3) edit specimen
4) change clinical trial
5) delete clinical trial
6) submit trial number for null clinical trial
7) new clinical trial
8) new trial number
9) change trial number
10) delete trial number
11) change request consent option
12) delete request consent option
13) new request consent options
14) new request_option
15) delete 1 & add 1 request_option
16) new external reference
17) change external reference
18) delete external reference
=cut

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

    use DateTime;
    DateTime->DefaultLocale('en_GB');
}

my $NOW = DateTime->now(); # needs to be as close as possible to db rebuild event

my $mech = get_mech();

my $dbh;

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

warn $@ if $@;

do_login();

# edit referrer:
$mech->get_ok('/search/=/2');                                 # print_and_exit();
{
    $mech->follow_link_ok(
        # {n => 8}, "Logout $_ via eighth link on page",
        { url_regex => qr(request/edit), },
        'edit request using link',
    );                                                        # print_and_exit();

    $mech->follow_link_ok(
        # {n => 8}, "Logout $_ via eighth link on page",
        { url_regex => qr(edit_request), },
        'edit request using link',
    );                                                        # print_and_exit();

    # check referrer:
    $mech->content_like(
        qr(id="referrer_name" value="Brown CC"),
        'OK: expected referrer detected'
    );                                                        # print_and_exit();
    $mech->content_lacks(
        'Cutter, S',
        'OK: intended new referrer name not found',
    );

    # check referral_source:
    $mech->content_like(
        qr(<input type="text"(.*)value="Newtown General Infirmary" />), 
        'OK: expected referral_source detected'
    );                                                     # print_and_exit();
    
    $mech->field( referrer_code => 'C7654321' );
    $mech->field( _referrer => 'Cutter S' ); # would be done automatically by form
    $mech->submit_form();                                     # print_and_exit();
    
    # need reason for edit:
    has_dfv_errors();                                       
    has_missing();                                            # print_and_exit();
    
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_edit_success(1);

    $mech->has_tag_like(
        span => qr(Cutter S),
        'OK: new referrer name detected',
    );                                                        # print_and_exit();
    
    # check still have same referral_source:
    $mech->has_tag_like(
        td => qr(Newtown General Infirmary), 
        'OK: original referral_source still present'
    );                                                       

    # check history: 
    $mech->get_ok('/history/=/2');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr/amended referrer \(Brown CC(.*)Cutter S\)/,
        'OK: expected history found',
    );                                                       #  print_and_exit();
}

# now change referrer to unknown:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/2');      

    # check referrer:
    $mech->content_like(
        qr(id="referrer_name" value="Cutter S"),
        'OK: expected referrer detected'
    );                                                      # print_and_exit();

    $mech->field( referrer_code => 'C9999998' );
    $mech->field( _referrer => 'Unknown clinician' ); # would be done automatically by form
    $mech->submit_form();                                     # print_and_exit();
    
    # need reason for edit:
    has_dfv_errors();                                       
    has_missing();                                            # print_and_exit();
    
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_edit_success(1);
    lacks_dfv_errors();                                       

    $mech->has_tag_like(
        span => qr(Unknown),
        'OK: unknown referrer detected',
    );                                                        # print_and_exit();

    # check still have original referral_source:
    $mech->has_tag_like(
        td => qr(Newtown General Infirmary), 
        'OK: original referral_source still present'
    );                                                        # print_and_exit();

    # check history: 
    $mech->get_ok('/history/=/2');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr/amended referrer \(Cutter S(.*)Unknown clinician\)/,
        'OK: expected history found',
    );                                                      #   print_and_exit();
}

# edit specimen code:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();
    
    # check specimen code:
    $mech->content_like(
        qr(name="specimen_code"(.*)\s+value="BMAT, PB"),
        'OK: expected specimen code detected',
    );                                                        # print_and_exit();
    
    $mech->field( specimen_code => 'LU, PB' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_edit_success(1);
    lacks_dfv_errors();                                       # print_and_exit();
    
    # check new specimen code:
    $mech->has_tag_like(
        span => qr(LU, PB),
        'OK: new specimen code found',
    );                                                        # print_and_exit();

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr/amended specimen \(BMAT, PB(.*)LU, PB\)/,
        'OK: expected history found',
    );                                                        # print_and_exit();    
}

# edit sample date
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');
    
    my $date = $NOW->clone->subtract( days => 1 );
    
    is( $mech->field($_), (sprintf '%02d', $date->$_), "OK: specimen date - $_" )
        for qw(year month day hour);                         # print_and_exit();

    { # if db tables rebuilt very close to minute roll-over, $NOW->minute 
        # will be +1 compared to request_specimen_detail.specimen_date:
        my $minute_value = $mech->field('minute'); # warn $minute_value;
        my @possible_vals
            = ( $date->minute, $date->clone->subtract( minutes => 1 ) );
        ok( grep( $minute_value, @possible_vals ), 'OK: specimen date - minute' );
    }

    # subtract 1 day & submit:
    $date->subtract( days => 1 );
    $mech->field( $_ => $date->$_ ) for qw(year month day hour minute);
    $mech->field( error_code_id =>1 );
    $mech->submit();                                          
    has_edit_success(1);                                      # print_and_exit();
    
    # bring edit page back to test specimen date:
    $mech->get_ok('/request/edit_request/1');

    is( $mech->field($_), (sprintf '%02d', $date->$_), "OK: specimen date - $_" )
        for qw(year month day hour minute);                 # print_and_exit();
}                                                            

# change clinical trial:
my $new_trial = 'NCRI: Myeloma X';
my $old_trial = 'HMDS outreach';

{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();
    
    # check trial selected:
    $mech->content_like(
        qr/option value="1"(\s+)selected/,
        'OK: correct trial selected',
    );
    
    # change trial:
    $mech->field( trial_id => 2 );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_edit_success(1);
    $mech->text_contains(
        'Clinical trial: ' . $old_trial,
        'OK: trial change successful',
    );                                                       #  print_and_exit();
    $mech->content_lacks(
        $new_trial,
        'OK: old trial name not detected',
    );                                                        # print_and_exit();
    
    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr/changed clinical trial \($new_trial -> $old_trial\)/,
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# delete clinical trial:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();
    
    # check trial selected:
    $mech->content_like(
        qr/option value="2"(\s+)selected/,
        'OK: correct trial selected',
    );
    
    $mech->field( trial_id => '' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # just check for absence of expected trial:
    $mech->content_lacks(
        $old_trial,
        'OK: deleted trial name not found',
    );
    
    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr(deleted clinical trial $old_trial),
        'OK: expected history found',
    );                                                        # print_and_exit();

}

# try to submit trial number against null clinical trial:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();
    
    $mech->field( trial_number => 'ABC123' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_dfv_errors();
    has_missing();
}

# new clinical trial:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();

    # check no trial selected:
    is(
       $mech->value('trial_id', 1),
       '',
       'OK: no trial selected'
    );                                                        # print_and_exit();
    
    $mech->field( trial_id => '1' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    $mech->text_contains(
        'Clinical trial: ' . $new_trial,
        'OK: new trial name found',
    );                                                        # print_and_exit();

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr(new clinical trial $new_trial),
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# new trial number:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();
    
    $mech->field( trial_number => '001' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    $mech->text_like(
        qr/Clinical trial: $new_trial(\s+)\[ 001 \]/,
        'OK: new trial number successful',
    );                                                        # print_and_exit();
    
    has_edit_success(1);
    
    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr/new trial number 001/,
        'OK: expected history found',
    );                                                        # print_and_exit();
}
# change trial number:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();
    
    
    $mech->field( trial_number => '123/456' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_edit_success(1);
    
    $mech->text_like(
        qr($new_trial(\s+)\[ 123/456 \]),
        'OK: trial number change successful',
    );                                                        # print_and_exit();
    
    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr{changed trial number \(001 (.*) 123/456\)},
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# delete trial number:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();
    
    
    $mech->field( trial_number => '' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_edit_success(1);
    
    test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag_like( p => qr($new_trial(\s+)\[ (.*) \]), 'foo' );
    test_test( 'OK: trial number delete successful' );        # print_and_exit();

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();
    
    $mech->has_tag_like(
        td => qr{deleted trial number 123/456},
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# change request consent:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('treatment', 1), 'yes', 'OK: expected consent found' );
    is( $mech->value('research',  1), '',    'OK: expected consent found' );
    
    # change treatment to 'no':
    $mech->field( treatment => 'no' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('treatment', 1), 'no', 'OK: expected consent found' );
    is( $mech->value('research',  1), '',   'OK: expected consent found' );

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(updated treatment consent data \[yes (.*) no\]),
        'OK: expected history found',
    );                                                        # print_and_exit();
}
# delete request consent:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('treatment', 1), 'no', 'OK: expected consent found' );
    is( $mech->value('research',  1), '',   'OK: expected consent found' );
    
    # change treatment to 'no':
    $mech->field( treatment => '' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('treatment', 1), '', 'OK: expected consent found' );
    is( $mech->value('research',  1), '', 'OK: expected consent found' );

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(deleted consent data),
        'OK: expected history found',
    );                                                        # print_and_exit();
}
# 2 new request consents:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('treatment', 1), '', 'OK: expected consent found' );
    is( $mech->value('research',  1), '', 'OK: expected consent found' );
    
    $mech->field( treatment => 'no' );
    $mech->field( research => 'yes' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('treatment', 1), 'no',  'OK: expected consent found' );
    is( $mech->value('research',  1), 'yes', 'OK: expected consent found' );

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(updated treatment consent data \[\? (.*) no\]),
        'OK: expected history found',
    );                                                        # print_and_exit();
    $mech->has_tag_like(
        td => qr(updated research consent data \[\? (.*) yes\]),
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# new request_option:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();

    # check doi & urgent not flagged:
    is( $mech->value('doi',    1), undef, 'OK: expected option value found' );
    is( $mech->value('urgent', 1), undef, 'OK: expected option value found' );
    
    # set urgent on:
    $mech->tick( 'urgent', 1, 1 );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('doi',    1), undef, 'OK: expected option value found' );
    is( $mech->value('urgent', 1), 1,     'OK: expected option value found' );

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(new request option 'urgent'),
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# delete 1 & request 1 request_option:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();

    # check doi & urgent not flagged:
    is( $mech->value('doi',    1), undef, 'OK: expected option value found' );
    is( $mech->value('urgent', 1), 1,     'OK: expected option value found' );
    
    # set urgent off & doi on:
    $mech->tick( 'doi', 1, 1 );
    $mech->untick( 'urgent', 1 );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check treatment = yes & research = no:
    is( $mech->value('doi',    1), 1,     'OK: expected option value found' );
    is( $mech->value('urgent', 1), undef, 'OK: expected option value found' );

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(deleted request option 'urgent'),
        'OK: expected history found',
    );                                                        # print_and_exit();
    $mech->has_tag_like(
        td => qr(new request option 'doi'),
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# new external ref:
{
    # load request_edit page direct:
    $mech->get_ok('/request/edit_request/1');                 # print_and_exit();

    # check null value:
    is(
       $mech->value('external_reference', 1),
       '',
       'OK: null external ref found'
    );
    
    # new external ref value:
    $mech->field( external_reference => 'ABC/123' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check new value found:
    is(
       $mech->value('external_reference', 1),
       'ABC/123',
       'OK: new external ref found'
    );
    
    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(new external reference),
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# change external ref:
{
    # load request_edit page direct:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check value:
    is(
       $mech->value('external_reference', 1),
       'ABC/123',
       'OK: new external ref found'
    );
    
    # change value:
    $mech->field( external_reference => 'DEF/456' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check value:
    is(
       $mech->value('external_reference', 1),
       'DEF/456',
       'OK: changed external ref value found'
    );

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(changed external ref \[ABC/123 to DEF/456\]),
        'OK: expected history found',
    );                                                        # print_and_exit();
}

# delete external ref:
{
    # load request_edit page direct:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check value:
    is(
       $mech->value('external_reference', 1),
       'DEF/456',
       'OK: expected external ref value'
    );
    
    $mech->field( external_reference => '' );
    $mech->field( error_code_id =>1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);

    # need to get edit page back to check value:
    $mech->get('/request/edit_request/1');                    # print_and_exit();

    # check null value:
    is(
       $mech->value('external_reference', 1),
       '',
       'OK: null external ref found'
    );

    # check history: 
    $mech->get_ok('/history/=/1');                            # print_and_exit();

    $mech->has_tag_like(
        td => qr(deleted external reference),
        'OK: expected history found',
    );                                                        # print_and_exit();
}

do_logout();

sub has_edit_success {
    my $i = shift;
    my $msg = sprintf get_messages('request_edit')->{edit_success}, $i;
    
    $msg =~ s/([\(\)])/\\$1/g; # need to escape parens or qr fails

    $mech->has_tag_like(
        p => qr(INFO: $msg),
        'OK: edit action succeeded',
    );
}
