package LIMS::Controller::Error;

use base 'LIMS::Base';

use Moose;
	with (
		'LIMS::Controller::Roles::User',
#		'LIMS::Controller::Roles::DataMap'
	);
	
use Data::Dumper;

# ------------------------------------------------------------------------------
# default() should never be called direct - redirect to start page:
sub default : StartRunmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);

    return $self->redirect( $self->query->url );
}

# ------------------------------------------------------------------------------
sub load : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);
    my $errs = shift; # $self->stash( errs => $errs );
	
    return $self->forbidden() unless $self->user_can('log_errors');
    
    my $request_id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);

	# stash request_id for template:
	$self->stash(request_id => $request_id);

    {
        my $data = $self->model('Request')->get_request_errors($request_id);
        $self->tt_params( data => $data );
        
        # get codes in use to prevent reuse of unique ones:
        my %codes = map { $_->error_code_id => 1 } @$data; # warn Dumper \%used;
        $self->tt_params( codes_in_use => \%codes );
    }
	{
        my $error_codes
            = $self->model('ErrorCode')->get_error_code_assignment('errors');		
        $self->tt_params( error_codes => $error_codes );
    }
    
	$self->js_validation_profile('request_error');

    return $self->tt_process('error/default.tt', $errs);
}

#-------------------------------------------------------------------------------
sub edit : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);
    
	return $self->forbidden() unless $self->user_can('edit_pid');

    my $request_id = $self->param('id')
    || return $self->error('no request id passed to ' . $self->get_current_runmode);

    my $id = $self->param('Id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);

    { # get error to edit:
        my $error = $self->model('Request')->get_request_error_code($id);
        $self->tt_params( error => $error );
    }
    { # get all application error codes:
        my $error_codes = $self->model('ErrorCode')->get_error_codes();
        $self->tt_params( error_codes => $error_codes );
    }
    { # get all errors on this request (need to prevent reuse of unique codes):
        my $errors = $self->model('Request')->get_request_errors($request_id);
        my %codes = map { $_->error_code_id => 1 } @$errors; # warn Dumper \%used;
        $self->tt_params( codes_in_use => \%codes );        
    }    

	$self->js_validation_profile('request_error');

    return $self->tt_process();
}

#-------------------------------------------------------------------------------
sub do_edit : Runmode { # updates request error_code - can't use update() - uses request_id
    my $self = shift; $self->_debug_path($self->get_current_runmode);
    
	return $self->forbidden() unless $self->user_can('edit_pid');

    my $request_id = $self->param('id')
    || return $self->error('no request id passed to ' . $self->get_current_runmode);

    my $id = $self->param('Id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);

    my $dfv = $self->check_rm('load', $self->validate('request_error') )
	|| return $self->dfv_error_page;

    my $data = $dfv->valid(); # $self->debug($data);
    
    # put record_id into $data:
    $data->{id} = $id;

    my $rtn = $self->model('Request')->edit_request_error_code($data);

    if ($rtn) {
        return $self->error($rtn);
	}
	else {
		$self->flash( info => $self->messages('action')->{edit_success} );
		return $self->redirect( $self->query->url . '/error/=/' . $request_id );
	}
}

#-------------------------------------------------------------------------------
sub update : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);
    
    my $request_id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);

    my $dfv = $self->check_rm('load', $self->validate('request_error') )
	|| return $self->dfv_error_page;

    my $data = $dfv->valid(); # $self->debug($data);

    # put request_id into $data:
    $data->{request_id} = $request_id;
	
    my $rtn = $self->model('Request')->request_error_code($data);

    if ($rtn) {
        return $self->error($rtn);
	}
	else {
		$self->flash( info => $self->messages('action')->{create_success} );
		return $self->redirect( $self->query->url . '/error/=/' . $request_id );
	}
}

#-------------------------------------------------------------------------------
sub delete : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);
    
	return $self->forbidden() unless $self->user_can('edit_pid');

    my $id = $self->param('id')
    || return $self->error('no id passed to ' . $self->get_current_runmode);
    
    my $error = $self->model('Request')->get_request_error_code($id);

    # need confirmation to delete record:
    if ( $self->query->param('confirm_delete') ) {
        my $rtn = $self->model('Request')->delete_request_error_code($id);
        return $self->error($rtn) if $rtn;
        
        # set flash success & redirect:
        $self->flash( info => $self->messages('action')->{delete_success} );
        $self->redirect( $self->query->url . '/search/=/' . $error->request_id );
    }
    else { # just load error for confirmation:
        $self->tt_params( error => $error );
        return $self->tt_process();
    }
}
    
#-------------------------------------------------------------------------------
# method to handle system error submission to admin:
sub notify : Runmode {
    my $self = shift; $self->_debug_path($self->get_current_runmode);
    
    my $vars = $self->query->Vars(); # warn Dumper $vars;
    # add current username to $vars:
    $vars->{user} = uc $self->authen->username;
    
    my $subject = 'HILIS4 system error';
    my $config = $self->cfg('settings');
    
    my $recipient = $config->{admin_contact};
    my $message =
        sprintf "class: %s\nline: %s\ntime: %s\nerror: %s\nuser: %s\naction: %s",
        map $vars->{$_}, qw(package line time message user action); 

    my %mail_data = (
        recipient => $recipient,
        subject   => $subject,
        message   => $message,
        config    => $config,
    ); # $self->debug(\%mail_data); 

    my $rtn = $self->model('Email')->send_message(\%mail_data); # Return::Value object
    return $self->tt_process({ msg => $rtn->string });
}

1;
