package FixMyStreet::App::Form::Role;

use HTML::FormHandler::Moose;
use FixMyStreet::App::Form::I18N;
extends 'HTML::FormHandler::Model::DBIC';
use namespace::autoclean;

has 'body_id' => ( isa => 'Int', is => 'ro' );
has 'categories' => ( isa => 'Maybe[ArrayRef[Int]]', is => 'rw' );

has '+widget_name_space' => ( default => sub { ['FixMyStreet::App::Form::Widget'] } );
has '+widget_tags' => ( default => sub { { wrapper_tag => 'p' } } );
has '+item_class' => ( default => 'Role' );
has_field 'name' => ( required => 1 );
has_field 'body' => ( type => 'Select', empty_select => 'Select a body', required => 1 );
has_field 'permissions' => (
    type => 'Multiple',
    widget => 'CheckboxGroup',
    ul_class => 'permissions-checkboxes',
    tags => { inline => 1, wrapper_tag => 'fieldset', },
);

before 'update_model' => sub {
    my $self = shift;
    $self->item->body_id($self->body_id) if $self->body_id;
    $self->item->set_extra_metadata('categories', $self->categories);
};

sub _build_language_handle { FixMyStreet::App::Form::I18N->new }

has '+unique_messages' => (
   default => sub {
      { roles_body_id_name_key => "Role names must be unique" };
   }
);

sub validate {
    my $self = shift;

    my $rs = $self->resultset;
    my $value = $self->value;

    return 0 if $self->body_id; # The core validation catches this, because body_id is set on $self->item
    return 0 if $self->item_id && $self->item->body_id == $value->{body}; # Correctly caught by core validation

    # Okay, due to a bug we need to check this ourselves
    # https://github.com/gshank/html-formhandler-model-dbic/issues/20
    my @id_clause = ();
    @id_clause = HTML::FormHandler::Model::DBIC::_id_clause( $rs, $self->item_id ) if defined $self->item;

    my %form_columns = (body => 'body_id', name => 'name');
    my %where = map { $form_columns{$_} =>
        exists( $value->{$_} ) ? $value->{$_} : undef ||
            ( $self->item ? $self->item->get_column($form_columns{$_}) : undef )
    } keys %form_columns;

    my $count = $rs->search( \%where )->search( {@id_clause} )->count;
    return 0 if $count < 1;

    my $field = $self->field('name');
    my $constraint = 'roles_body_id_name_key';
    my $field_error = $self->unique_message_for_constraint($constraint);
    $field->add_error( $field_error, $constraint );
    return 1;
}

__PACKAGE__->meta->make_immutable;

1;
