#!/usr/bin/perl

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

use strict;
use warnings;

use Data::Printer;
use POSIX;

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

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

ok( get_yaml('storage') , "require a storage.yml file" ); # check for required yaml file

my $mech = get_mech();

my $dbh;

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

warn $@ if $@;

my $dbix = get_dbix();

do_login();

my %data = (
    1 => {
        part_number => '1a',
        specimen => 'PB',
        vialId => 1234567890,
        source => 'liquid',
        sample => 'serum',
    },
    2 => {
        part_number => '2a',
        specimen => 'BMAT',
        vialId => 'FR12345678',
        source => 'liquid',
        sample => 'dna',
    },
);
$mech->get_ok('/storage/=/1');                               # print_and_exit();
{ # non-xna sample - doesn't require volume & concentration
    my %h = %{ $data{1} };

    # test each required field:
    foreach my $field ( keys %h ) { # warn $field;
        # create temp hash with one field missing:
        my %tmp = %{ $data{1} };
        $tmp{$field} = undef; # warn Dumper \%tmp_user;

        $mech->submit_form(
            form_name => 'storageVial', # 1st one is to request new lab-tests
            fields => \%tmp,
        );
        has_dfv_errors();
    }

    { # invalid vialId length
        my %tmp = %{ $data{1} };
        $tmp{vialId} /= 10; # warn $tmp{vialId};
        $mech->submit_form(
            form_name => 'storageVial', # 1st one is to request new lab-tests
            fields => \%tmp,
        );
        # check we have success message:
        $mech->content_contains(
            'invalid length',
            'OK: invalid vialId length',
        );                                                   # print_and_exit();
    }
    # submit valid form:
    $mech->submit_form(
        form_name => 'storageVial', # 1st one is to request new lab-tests
        fields => \%h,
    );                                                       # print_and_exit();

    # check we have success message:
    $mech->content_contains(
        get_messages('action')->{create_success},
        'OK: new record created successfully',
    );                                                        # print_and_exit();

    $mech->has_tag(
        p => 'Number of vials in store: 1',
        'OK: expected number of vials',
    );

    $mech->text_contains(
        'Available vials to sign out: ' . $h{vialId},
        'OK: vialId available to sign-out',
    );                                                       # print_and_exit();

    foreach my $field ( keys %h ) { # warn $field;
        $mech->has_tag(
            td => $h{$field},
            "OK: expected value for $field found"
        );
    }                                                        # print_and_exit();
}
$mech->get_ok('/history/=/1');                               # print_and_exit();
{
    $mech->has_tag(
        td => 'scanned in vialId ' . $data{1}{vialId},
        'OK expected history entry found',
    );
}
$mech->get_ok('/storage/=/1');                               # print_and_exit();
{
    # sign vial out:
    $mech->submit_form(
        form_number => 3,
        fields => { vialId => $data{1}{vialId} },
    );                                                       # print_and_exit();
    # check we have success message:
    $mech->content_contains(
        get_messages('action')->{edit_success},
        'OK: record updated successfully',
    );                                                        # print_and_exit();

    $mech->has_tag(
        p => 'Number of vials in store: 0',
        'OK: expected number of vials',
    );
}
$mech->get_ok('/history/=/1');                               # print_and_exit();
{
    $mech->has_tag(
        td => 'scanned out vialId ' . $data{1}{vialId},
        'OK expected history entry found',
    );
}

# dna sample:
$mech->get_ok('/storage/=/1');                               # print_and_exit();
{ # dna sample - requires volume & concentration
    my $h = $data{2};
    # submit incomplete form:
    $mech->submit_form(
        form_name => 'storageVial', # 1st one is to request new lab-tests
        fields => $h,
    );                                                       # print_and_exit();
    has_dfv_errors();

    my %tmp = %$h;

    $tmp{volume} = 160;
    $mech->submit_form(
        form_name => 'storageVial', # 1st one is to request new lab-tests
        fields => \%tmp,
    );                                                       # print_and_exit();
    has_dfv_errors();

    $tmp{concentration} = 60;
    $mech->submit_form(
        form_name => 'storageVial', # 1st one is to request new lab-tests
        fields => \%tmp,
    );                                                       # print_and_exit();
    has_dfv_errors();

    $tmp{method} = 'Qiagen';
    $mech->submit_form(
        form_name => 'storageVial', # 1st one is to request new lab-tests
        fields => \%tmp,
    );                                                       # print_and_exit();
    # check we have success message:
    $mech->content_contains(
        get_messages('action')->{create_success},
        'OK: new record created successfully',
    );                                                       # print_and_exit();

    # should only have 1 vial:
    $mech->has_tag(
        p => 'Number of vials in store: 1',
        'OK: expected number of vials',
    );                                                       # print_and_exit();

    # can't scan same vial in twice:
    $mech->submit_form(
        form_name => 'storageVial', # 1st one is to request new lab-tests
        fields => \%tmp,
    );                                                       # print_and_exit();
    $mech->text_contains(
        get_messages('dfv_msgs')->{not_unique},
        'OK: duplicate vialId detected',
    );                                                        # print_and_exit();
}

# edit vial:
$mech->get_ok(sprintf '/storage/edit/%s/1', $data{2}{vialId});# print_and_exit();
{
    my %tmp = %{ $data{2} };

    # delete volume entry:
    $tmp{volume} = undef; # p %tmp;

    # submit incomplete form:
    $mech->submit_form( fields => \%tmp );                   # print_and_exit();                                                      print_and_exit();
    has_dfv_errors();                                        # print_and_exit();

    $mech->text_contains(
        'Volume « missing', # '«' = Alt-0171 in keypad
        'OK: volume value missing',
    );                                                       # print_and_exit();
}
$mech->get_ok(sprintf '/storage/edit/%s/1', $data{2}{vialId});# print_and_exit();
{
    my %tmp = %{ $data{2} };

    $tmp{volume} = 260;
    $mech->submit_form( fields => \%tmp );                   # print_and_exit();                                                   print_and_exit();

    foreach my $field ( keys %tmp ) { # warn $field;
        $mech->has_tag_like(
            td => qr/$tmp{$field}/,
            "OK: expected value for $field found"
        );
    }                                                        # print_and_exit();
}
$mech->get_ok('/history/=/1');                               # print_and_exit();
{
    $mech->has_tag(
        td => ( sprintf 'updated vial %s volume entry', $data{2}{vialId} ),
        'OK: updated volume value',
    );                                                       # print_and_exit();
}

$mech->get_ok('/storage/read_xtr_96');                       # print_and_exit();
{
    $mech->form_name('scan');
    $mech->submit();                                         # print_and_exit();
    $mech->text_contains(
        'Warning: unknown vial(s) present',
        'OK: detected unknown vial IDs',
    );

    # manually add data to request_storage table:
    my $data = _plate_data();
    my %h = (
        sample        => 'dna',
        volume        => 200,
        source        => 'liquid',
        method        => 'Qiagen',
        vialId        => undef, # supplied in loop
        request_id    => 1,
        specimen_id   => 1,
        part_number   => 1,
        vial_location => undef, # supplied in loop
        concentration => 50,
    );
    while ( ($h{vial_location}, $h{vialId}) = each %$data ) {
        $h{part_number}++; # create unique
        $dbix->insert('request_storage', \%h);
    }
    $mech->form_name('scan');
    $mech->submit();                                          print_and_exit();

}

sub _plate_data {
    my $i = 1000000001; # 10 digit number
    my @cells = map { $_ . '01' .. $_ . '12' } ( 'A' .. 'H' ); # p @cells;
    my %h = map { $_ => $i++ } @cells; # p %h;
    return \%h;
}
