use strict;
use warnings;

=head1 NAME

Liberl::Action::AddBook

=cut

package Liberl::Action::AddBook;
use base qw/Liberl::Action Jifty::Action/;

use LWP::Simple;
use Data::Random "rand_chars";

use Jifty::Param::Schema;
use Jifty::Action schema {
    param title =>
        label is _('Title'),
        is mandatory,
        ;

    param authors =>
        label is _('Authors'),
        render as 'textarea',
        autocompleter is \&complete_authors,
        ;

    param publisher =>
        label is _('Publisher'),
        ;

    param isbn =>
        label is _('ISBN'),
        ;

    param edition =>
        label is _('Edition'),
        ;

    param numpages =>
        label is _('Pages'),
        ;

    param publication_date =>
        label is _('Publication date'),
        ;

    param library =>
        label is _('Library'),
        render as 'select',
        is mandatory,
        available are defer {
            my $libraries = Liberl::Model::LibraryCollection->new;
            $libraries->unlimit;
            [{
                display_from => 'name',
                value_from   => 'name',
                collection   => $libraries,
             }];
    };

    param format =>
        label is _('Format'),
        render as 'select',
        is mandatory,
        available are defer {
            my $formats = Liberl::Model::FormatCollection->new;
            $formats->unlimit;
            [{
                display_from => 'name',
                value_from   => 'name',
                collection   => $formats,
             }];
    };

    param categories =>
        label is _('Categories'),
        ;

    param description =>
        label is _('Description'),
        render as 'Textarea',
        ;

    param ImageUrlSmall =>
        render as 'Hidden',
        ;
    param ImageUrlMedium =>
        render as 'Hidden',
        ;
    param ImageUrlLarge =>
        render as 'Hidden',
        ;

    param cover =>
        label is _('Cover'),
        render as 'Upload',
        ;
};

=head2 take_action

=cut

sub take_action {
    my $self = shift;
    my $title            = $self->argument_value('title');
    my $authors          = $self->argument_value('authors');
    my $publisher_name   = $self->argument_value('publisher');
    my $library_name     = $self->argument_value('library');
    my $format_name      = $self->argument_value('format');

    my $publisher = Liberl::Model::Publisher->load_by_cols(
        name => $publisher_name,
        );
    if (! $publisher->id) {
        $publisher = Liberl::Model::Publisher->create(
            name => $publisher_name,
            );
    }

    my $library = Liberl::Model::Library->load_by_cols(
        name => $library_name,
        );

    my $format = Liberl::Model::Format->load_by_cols(
        name => $format_name,
        );

    my $cover_key = join('', rand_chars(set => 'alphanumeric',
                                  min => 16,
                                  max => 20)
        );

    my $book = Liberl::Model::Book->new;
    $book->create(
        title            => $title,
        description      => $self->argument_value('description'),
        publisher        => $publisher,
        library          => $library,
        format           => $format,
        isbn             => $self->argument_value('isbn'),
        edition          => $self->argument_value('edition'),
        numpages         => $self->argument_value('numpages'),
        publication_date => $self->argument_value('publication_date'),
        owner            => Jifty->web->current_user->id,
        cover_key        => $cover_key,
        );

    my @authors = split(/\n/, $authors);
    for (@authors) {
        next if /^\s*$/;

        my ($firstname, $lastname) = firstlastname($_);

        my $author = Liberl::Model::Author->load_by_cols(
            firstname => $firstname,
            lastname  => $lastname,
            );
        if (! $author->id) {
            $author = Liberl::Model::Author->create(
                firstname => $firstname,
                lastname  => $lastname,
                );
        }

        my $link = Liberl::Model::LinkBookAuthor->new;
        $link->create(
            author => $author,
            book   => $book,
            );
    }
 
    getstore($self->argument_value('ImageUrlSmall'),  "share/web/static/covers/small/${cover_key}.jpg" );
    getstore($self->argument_value('ImageUrlMedium'), "share/web/static/covers/medium/${cover_key}.jpg");
    getstore($self->argument_value('ImageUrlLarge'),  "share/web/static/covers/large/${cover_key}.jpg" );

    $self->result->content(title => $title);
    $self->report_success if not $self->result->failure;

    return 1;
}

=head2 report_success

=cut

sub report_success {
    my $self = shift;
    # Your success message here
    $self->result->message(_('Success'));
}

=head2 validate_title

Check if the title is not empty

=cut

sub validate_title {
    my $self = shift;
    my $title = shift;

    if ($title =~ /\s*/) {
        return $self->validation_error(title => _('You can\'t add a book with an empty title !'));
    }
    else {
        return $self->validation_ok('title');
    }
}

=head2 complete_authors

=cut

sub complete_authors {
    my $self = shift;
    my $text_authors = shift;

    my @authors = split(/\n/, $text_authors);
    my $search = $authors[@authors - 1];
    my $column = 'lastname';

    my ($first, $last) = firstlastname($search);

    if (length $last >= 3) {
        $search = $last;
        $column = 'lastname';
    }
    else {
        if (length $first >= 3) {
            $search = $first;
            $column = 'firstname';
        }
        else {
            return
        }
    }

    my $authors = Liberl::Model::AuthorCollection->new;
    $authors->limit(
        column => $column,
        value  => $search,
        operator => 'MATCHES',
        );

    my @names = ();
    while (my $author = $authors->next) {
        push @names, $author->lastname . ", " . $author->firstname;
    }

    return @names;
}

=head2 complete_publisher

=cut

sub complete_publisher {
    my $self = shift;
    my $search = shift;

    my @names = ();

    if (length $search >= 3) {
        my $publishers = Liberl::Model::PublisherCollection->new;
        $publishers->limit(
            column => 'name',
            value  => $search,
            operator => 'MATCHES',
        );

        while (my $publisher = $publishers->next) {
            push @names, $publisher->name;
        }
    }
    return @names;
}

=head2 firstlastname

Split a string in firtname and lastname parts

=cut

sub firstlastname {
    my $name = shift;

    if (defined $name) {
        my ($firstname, $lastname);
        if ($name =~ m/,/) {
            ($lastname, $firstname) = split(/\s*,\s*/, $name);
        }
        else  {
            if ($name =~ m/\s+/) {
                my @lastname = ();
                ($firstname, @lastname) = split(/\s+/, $name);
                $lastname = join(' ', @lastname);
            }
            else {
                $lastname  = $name;
                $firstname = "";
            }
        }
        return ($firstname, $lastname)
    }
    else {
        return "","";
    }
}

=head2 canonicalize_isbn

=cut

sub canonicalize_isbn {
    my $self = shift;
    my $isbn = shift;

    my $number = Business::ISBN->new($isbn);
    if (defined($number)) {
        if ($number->is_valid) {
            return $number->as_isbn13->as_string([]);
        }
    }
    return $isbn;
}

1;

