#!/usr/bin/perl

use DateTime;
use Data::Dumper;
use Test::Builder::Tester;
use Test::WWW::Mechanize::CGIApp;

use strict;
use warnings;

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

=begin # tests:
0) create new data for tests - outcome not tested
1) update nothing just test required field error_code
2) update day value in dob
3) change nhs_number to make identical entry to one already existing
=cut

require 't/test-lib.pl';

my $mech = get_mech();

# login/logout tests handled by test-lib.pl

do_login();   # print $fh $mech->content; # exit;

# create some new patient/request/patient_case records for this test suite:
{
    my $dbix = get_dbix();
    
    my $year = DateTime->now->year();
    my $now  = DateTime->now();
    
    # new data:
    my %new = (
        patients => [
            [ qw( green alan 1940-02-11 M ), undef, $now ], # duplicate of #1 without nhs_no
        ],
        patient_case => [ # patient_id, referral_source_id, unit_number
            [ 3, 2, 1011 ],
        ],
        requests => [ # yr, request_id, patient_case_id, referrer_dept_id, now 
            [ $year, 3, 3, 2, $now ], # hospital referral 
        ],
        request_specimen => [ # request_id, specimen_id
            [ 3, 1 ],
        ],
    );

    my $test_data = get_test_data();

    while ( my ($tbl, $data) = each %new ) { # warn $tbl, "\n";
        my $fields = $test_data->{$tbl}->{fields}; # warn Dumper $fields;

        foreach my $data_set (@$data) { # warn $data_set, "\n";
            my $i = 0;
            # map field_name to its value:
            my %data = map { $fields->[$i++] => $_ } @$data_set; # warn Dumper \%data;

            $dbix->insert($tbl, \%data);
        }
    }
}

{ # update nothing just test required field error_code:
    
    # load request_edit page direct:
    $mech->get_ok('/search/=/3');                             # print_and_exit();
    
    $mech->follow_link_ok(
        # {n => 8}, "Logout $_ via eighth link on page",
        { url_regex => qr(patient/edit_patient), },
        'edit patient using link',
    );                                                        # print_and_exit();

    # no changes, just tests 'error_code':
    $mech->submit_form();                                     # print_and_exit();
    
    has_dfv_errors();
    has_missing();

    $mech->field( error_code_id => 1 );
    $mech->submit_form();                                     # print_and_exit();
    
    # should have 'no changes' msg instead of 'edit success':
    $mech->content_lacks(
        get_messages('action')->{edit_success},
        'OK: edit success message not present',
    );    
    $mech->content_contains(
        get_messages('request_edit')->{edit_failed},
        'OK: no changes detected message present',
    );                                                        # print_and_exit();
}

# update day value in dob:
{
    $mech->get_ok('/patient/edit_patient/3/3');               # print_and_exit();
    
    $mech->field(day => 1);
    $mech->field( error_code_id => 1 );
    $mech->submit_form();                                     # print_and_exit();

    has_edit_success(1);
    
    # check fields are as expected:
    $mech->content_contains(
        '01.Feb.1940',
        'OK: new dob value detected',
    );
    test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag( td => '21.Feb.1940', 'foo' );
    test_test( 'OK: old dob value not detected' );            # print_and_exit();
    
    
    # check history: 
    $mech->get_ok('/history/=/3');                            # print_and_exit();
    
    $mech->has_tag_like(
        h3 => 'Patient demographics',
        'OK: expected history found',
    );                                                        # print_and_exit();
    foreach ( qw/dob 11-02-1940 01-02-1940/ ) {
        $mech->has_tag(
            td => $_,
            'OK: expected history found',
        );                                                    # print_and_exit();
    }
}

# change nhs_number to make identical entry to one already existing:
{
    my $null_nhs_number = '<!-- BEGIN nhs_number.tt -->'
    . '(\s+)<span class="grey">\[NULL\]</span><!-- END nhs_number.tt -->';

    # first make sure both records exist on green:
    $mech->get('/search/do_search?last_name=green;entries_per_page=10');
    #print_and_exit();
    $mech->text_contains(
        'Search returned 2 matches',
        'OK: expected number of records returned',
    );                                                        # print_and_exit();
    foreach ('111 111 1111','<span class="grey">\[NULL\]</span>') {
        $mech->content_like(
            qr(<!-- BEGIN nhs_number.tt -->(\s+)$_<!-- END nhs_number.tt -->),
            'OK: expected nhs_number found',
        );
    }                                                         # print_and_exit();
    
    $mech->get_ok('/search/=/3');                             # print_and_exit();
    # check nhs_number is null:
    $mech->content_like(
        qr($null_nhs_number),
        'OK: expected nhs_number found',
    );
    
    $mech->get_ok('/patient/edit_patient/3/3');               # print_and_exit();
    
    # check we have option of selecting other patient entry:
    $mech->has_tag(
        span => 'INFO: change affects this record only',
        'OK: single record change only',
    );
    
    # check similar patient data loaded:
    $mech->has_tag(
        p => 'Usage: select another patient record or edit current record',
        'OK: similar entries found'
    );
    
    foreach( qw/GREEN Alan 01.Feb.1940 1111111111/ ) {
        $mech->has_tag(
            td => $_,
            'OK: expected field detected'
        );
    }    
    
    $mech->has_tag_like(
        li => 1011,
        'OK: expected field detected'
    );

    $mech->field( nhs_number => 1111111111);
    $mech->field( error_code_id => 1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_dfv_errors();
    has_duplicate();                                          # print_and_exit();
    
    # select 'use this' instead:
    $mech->field( nhs_number => undef);
    $mech->field( use_patient_id => 1 );
    $mech->submit_form();                                     # print_and_exit();
    
    has_edit_success(1);
    
    # check nhs_number has changed:
    $mech->has_tag_like(
        td => qr(111 111 1111),
        'OK: new nhs_number found',
    );
    
    # retrieve both records on green:
    $mech->get('/search/do_search?last_name=green;entries_per_page=10');
    $mech->text_contains(
        'Search returned 2 matches',
        'OK: expected number of records returned',
    );                                                        # print_and_exit();
    $mech->has_tag_like(
        td => qr(111 111 1111),
        'OK: expected nhs_number found',
    );
    # shouldn't have old nhs_number anymore:
    test_out( 'not ok 1 - foo' );
    test_fail( +1 );
    $mech->has_tag_like( td => qr(\[NULL\]), 'foo' );
    test_test( 'OK: old nhs_number not detected' );           # print_and_exit();

    # check history: 
    $mech->get_ok('/history/=/3');                            # print_and_exit();
    $mech->get('/search/do_search?last_name=green;entries_per_page=10');
    #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 in edit_success msg or qr fails

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

