#!/usr/bin/perl

use Test::WWW::Mechanize::CGIApp;
# use HTML::TreeBuilder;
use Data::Dumper;

use strict;
use warnings;

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

=begin # tests:
1) try to allocate initial screen tests - error as no lab sections defined
2) register 1 lab section
3) try to allocate initial screen tests - error as no lab tests defined
4) register 3 lab tests + flow details - 1 lab test incorrect so needs correcting
5) try to allocate initial screen tests - error as no screening terms defined
6) register new screening term
7) edit new screen term
8) register 2nd screening term
9) allocate initial screen tests
10) edit selection of screen tests
11) delete flow details from initial screen test
12) try to register duplicate screen terms for different category (OK)
13) try to register duplicate screen terms for same category (not OK)
=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 drop & re-create following tables:
foreach ( qw/lab_tests lab_sections screens screen_lab_test screen_lab_test_detail/ ) {
    drop_and_recreate($_);
}

### Allocate Initial Screen Tests:
$mech->get_ok('/admin/screen_test');    #                     # print_and_exit();

### check error message:
$mech->content_contains(
    'ERROR: no lab sections defined',
    'error generated due to no lab sections defined',
);

### add new lab section:
$mech->get_ok('/admin/lab_section');                         # print_and_exit();

### check title:
$mech->content_contains(
    'Admin &raquo; Lab Sections',
    'title matches',
);                                     #                      # print_and_exit();

my $flow_section = 'Flow cytometry';

$mech->submit_form(
    fields => {
        section_name => $flow_section,
        has_result_summary => 'yes',
        has_section_notes => 'yes',
        sample_type_id => 0, # OK as already have 1,1 combination in test_data
    }
);                                                           #  print_and_exit();

### check section found:
$mech->content_like(
    qr!name="1"(\s*)value="$flow_section"!,
    'new entry value correct',
);                                                             #  print_and_exit;

### Allocate Initial Screen Tests:
$mech->get_ok('/admin/screen_test');                         # print_and_exit();

### check error message:
$mech->content_contains(
    'ERROR: no lab tests defined yet',
    'error generated due to no lab tests defined',
);

### add new lab test:
$mech->get_ok('/admin/lab_test');                           #  print_and_exit();

my %lab_tests = (
    1 => {
        field_label => 'Acute',
        test_name   => 'acute',
        test_type   => 'panel',
        lab_section_id  => 1,
    },
    2 => {
        field_label_bad   => 'exceeds max length 25 chars',
        field_label   => 'Lymph screen',
        test_name     => 'lymph_screen',
        test_type     => 'panel',
        lab_section_id    => 1,
    },
    3 => {
        field_label => 'p53',
        test_name   => 'p53',
        test_type   => 'panel',
        lab_section_id  => 1,
    },
);
=begin # function moved to section_notes:
#    4 => {
#        field_label => 'Flow details',
#        test_name   => 'flow_details',
#        field_type  => 'textarea',
#        lab_section_id  => 1,
#    },
=cut

# add new lab test #1
$mech->submit_form(fields => $lab_tests{1});                  # print_and_exit();

$mech->content_contains(
    qq!name="field_label" value="$lab_tests{1}{field_label}"!,
    'content_contains expected field_label',
);

$mech->content_contains(
    qq!option value="$lab_tests{1}{lab_section_id}" selected!,
    'content_contains expected section_id',
);

$mech->content_contains(
    qq!option value="$lab_tests{1}{test_type}"!,
    'content_contains expected test_type',
);

# add new lab test #2 - incorrect so will need to edit:
$mech->field('field_label',    $lab_tests{2}{field_label_bad});
$mech->field('test_type',      $lab_tests{2}{test_type});
$mech->field('test_name',      $lab_tests{2}{test_name});
$mech->field('lab_section_id', $lab_tests{2}{lab_section_id});
$mech->submit_form();                                         # print_and_exit();

### check error messages:
has_dfv_errors();
$mech->content_contains(
    dfv_format('too_long'),
    'OK: max field length exceeded',
);                                                            # print_and_exit();

### edit record to correct malformed field_label:
$mech->field('field_label', $lab_tests{2}{field_label});
$mech->submit_form();                                         # print_and_exit();

$mech->content_lacks(
    qq!name="field_label" value="$lab_tests{2}{field_label_bad}"!,
    'content_lacks malformed field_label',
);

$mech->content_contains(
    qq!name="field_label" value="$lab_tests{2}{field_label}"!,
    'content_contains corrected field_label',
);

$mech->content_contains(
    qq!option value="$lab_tests{2}{test_type}"!,
    'content_contains expected test_type',
);

$mech->content_contains(
    qq!option value="$lab_tests{2}{lab_section_id}" selected!,
    'content_contains expected section_id',
);

# add 3rd lab test:
$mech->submit_form(fields => $lab_tests{3});                  # print_and_exit();

$mech->content_contains(
    qq!name="field_label" value="$lab_tests{3}{field_label}"!,
    'content_contains expected field_label',
);

$mech->content_contains(
    qq!option value="$lab_tests{3}{test_type}"!,
    'content_contains expected etst_type',
);

$mech->content_contains(
    qq!option value="$lab_tests{3}{lab_section_id}" selected!,
    'content_contains expected section_id',
);

=begin # add 4th lab test:
$mech->submit_form(fields => $lab_tests{4});                    print_and_exit();

$mech->content_contains(
    qq!name="field_label" value="$lab_tests{4}{field_label}"!,
    'content_contains expected field_label',
);

$mech->content_contains(
    qq!name="test_name" value="$lab_tests{4}{test_name}"!,
    'content_contains expected test_name',
);

$mech->content_contains(
    qq!option value="$lab_tests{4}{field_type}"!,
    'content_contains expected field_type',
);

$mech->content_contains(
    qq!option value="$lab_tests{4}{lab_section_id}" selected!,
    'content_contains expected section_id',
);
=cut

### Allocate Initial Screen Tests:
$mech->get_ok('/admin/screen_test');    #                     # print_and_exit();


### check error message:
$mech->content_contains(
    'ERROR: no screening terms defined',
    'error generated due to no screening terms defined',
);

### add new screening term:
$mech->get_ok('/admin/screen_term');                         # print_and_exit();

my $first_term = 'AML follow-up';

$mech->field('description', $first_term);
$mech->select('category_id', 2 );
$mech->submit_form();                                         # print_and_exit();

=begin # too complex
my $tree = HTML::TreeBuilder->new_from_content($mech->content); # print Dumper $tree; exit; # don't - it's BIG
my $div = $tree->look_down(_tag => 'div', class => 'visible');
my @trs = $div->look_down(_tag => 'tr'); print Dumper map $_->as_text, @trs; exit; # ->as_text; exit;
=cut

### check input accepted:
$mech->content_contains(
    qq!name="description" value="$first_term"!,
    'first input description found',
);

$mech->content_contains(
    'option value="2" selected',
    'sample_type value correct',
);                                                            # print_and_exit();

### change sample_type - tests insert_or_update function:
$mech->get_ok('/admin/screen_term/edit/1');                   # print_and_exit();

$mech->select('category_id', 1);
$mech->submit_form();                                         # print_and_exit();

$mech->content_contains(
    'option value="1" selected',
    'changed sample_type value correct',
);                                                          #  print_and_exit();

my $second_term = 'DLBCL';

$mech->field('description', $second_term);
$mech->select('category_id', 2 );
$mech->submit_form();                                         # print_and_exit();

### check input accepted:
$mech->content_contains(
    qq!name="description" value="$first_term"!,
    'first input description found',
);

$mech->content_contains(
    qq!name="description" value="$second_term"!,
    'second input description found',
);

$mech->content_contains(
    'option value="2" selected',
    'sample_type value correct',
);

### Allocate Initial Screen Tests:
$mech->get_ok('/admin/screen_test');                         # print_and_exit();

$mech->content_contains(
    'Allocate Initial Screen Tests',
    'title check',
);

### select 1st menu item:
#$mech->select('id', { n => 1 });
#$mech->submit_form();  # can't do this now - using javascript select:
$mech->get_ok('/admin/screen_test?id=1');                     # print_and_exit();

### check 1st menu item loaded:
$mech->content_like(
    qr!<option value="1" selected>(\s*)$first_term(\s*)</option>!,
    'first input description found',
);                                                            # print_and_exit();

### check 1st menu item loaded:
$mech->content_contains(
    'no tests allocated',
    'no tests allocated yet',
);

foreach (1..3) {
    $mech->has_tag_like(
        td => qr($lab_tests{$_}{field_label}), 
        "expected field_label $_ [$lab_tests{$_}{field_label}] present",
    );
    $mech->content_like(
        qr(input type="checkbox" name="test_id"\s+value="$_"),
        "expected test id $_ present", # matches order of input, not hash entry
    );
}                                                             # print_and_exit();

$mech->content_like(
    qr(textarea name="lab_section_id_1"),
    'OK: text area present',
); # 

### select 2nd form:
$mech->form_name('update_screen_tests');                     # print_and_exit();

# check 1st 2 boxes:
for (1,2) {
    $mech->tick('test_id', $_, 1);
}

my $flow_details = 'Flow details text here';

$mech->field('lab_section_id_1', $flow_details); 

$mech->submit_form();                                         # print_and_exit();

$mech->has_tag_like(
    strong => qr($flow_section \[2\]),
    'correct section detected, correct number of tests',
);

for ('Acute', 'Lymph screen', 'p53') {
    $mech->has_tag_like(
        td => "$_:",
        "expected checkbox $_ detected",
    );
}

$mech->content_contains(
    $flow_details,
    'flow details string selected',
);                                                            # print_and_exit();

foreach (1,2) {
    $mech->has_tag_like(
        span => qr($lab_tests{$_}{field_label}),
        'correct allocated test detected',
    );
}                                                            #  print_and_exit();

$mech->follow_link_ok(
    # {n => 8}, "Logout $_ via eighth link on page",
    { url_regex => qr/list_all_screen_tests/i, },
    "follow 'List all' link on page",
);                                                           #  print_and_exit();

$mech->has_tag(
    dt => 'AML follow-up:',
    'OK: expected screen term found',
);

foreach ( 'Acute', 'Lymph screen' ) {
    $mech->has_tag(
        dd => "$_ (Flow cytometry)",
        'OK: expected test allocated',
    );    
}                                                             # print_and_exit();

$mech->back();

### select 2nd form:
$mech->form_name('update_screen_tests');

# remove lymph screen:
$mech->tick('test_id', 2, 0);

$mech->submit_form();                                         # print_and_exit();

$mech->has_tag_like(
    strong => qr($flow_section \[1\]),
    'correct section detected, correct number of tests',
);

$mech->content_contains( # has_tag_like gives fatal here - WTF ???
    qq!<span class="red">$lab_tests{1}{field_label}</span>!,
    'correct allocated test detected',
);                                                            # print_and_exit();

$mech->content_lacks(
    qq!<span class="red">$lab_tests{2}{field_label}</span>!,
    'de-allocated test not detected',
);                     # print_and_exit();

### select 2nd form:
$mech->form_name('update_screen_tests');

# change flow_details string:
$flow_details =~ s/here/edited/;

$mech->field('lab_section_id_1', $flow_details);

$mech->submit_form();                                         # print_and_exit();

$mech->content_contains(
    $flow_details,
    'amended flow details string detected',
);

### select 2nd form:
$mech->form_name('update_screen_tests');

# delete flow_details string:
$mech->field('lab_section_id_1', '');

$mech->submit_form();

$mech->has_tag_like(
    strong => qr($flow_section \[1\]),
    'correct section detected, correct number of tests',
);

$mech->content_lacks(
    $flow_details,
    'OK: flow details string NOT detected',
);

# try to register duplicate screen term in different category:
$mech->get_ok('/admin/screen_term');                         # print_and_exit();
{
    $mech->field('description', $second_term);
    $mech->select('category_id', 1 ); # was fixed, now fresh
    $mech->submit_form();                                     # print_and_exit();

    lacks_dfv_errors(); 
    $mech->content_contains(
        get_messages('action')->{edit_success},
        'OK: expected flash message detected',
    );                                                       # print_and_exit();
}
{
    $mech->field('description', $second_term);
    $mech->select('category_id', 1 ); # duplicate category for duplicate term
    $mech->submit_form();                                     # print_and_exit();

    ### check error messages:
    has_dfv_errors();
    $mech->content_contains(
        get_messages('admin')->{screen_term}->{not_unique},
        'OK: duplicate entry detected',
    );                                                       # print_and_exit();
}
# do_logout(); logout link not available for admin function
