package BookPub::RDAS::Parser::ProductSearch::Amazon;

use lib '/app/tools/bookpub/lib';
use base 'BookPub::RDAS::Parser::ProductSearch';

use lib '/app/tools/common/lib';
use Common::Assert;
use BookPub::RDAS::Parser::ProductSearch::Amazon::URL;

sub _validOptions {
    my @options = shift->SUPER::_validOptions();
    push( @options, bookID );
    return @options;
}

sub _fieldConfig {
    {
        URL => {
            tag       => 'table',
            container => 'BookPub::RDAS::Parser::ProductSearch::Amazon::URL',
        },

        Title => {
            tag   => 'span',
            class => 'srTitle',
        },

        Binding => {
            tag   => 'span',
            class => 'binding',
        },

        Author => {
            tag       => 'table',
            container => 'BookPub::RDAS::Parser::ProductSearch::Amazon::Author',
        },
    };
}

sub parentParser {
    my $self = shift;

    return $self->{_parentParser} if ( $self->{_parentParser} );

    $self->{_parentParser} = HTML::Tree->new();
    $self->{_parentParser}->parse( $self->content );

    return $self->{_parentParser};
}

sub parse {
    my $self = shift;

    my @results = $self->_getSearchResultItems();

    foreach my $node (@results) {
        $self->{_parser} = $node;

        $self->_clearCache();

        $self->SUPER::parse();

        if (   $self->_matchTitle( title => $self->Title, contains => 1 )
            && $self->_matchAuthor( author => $self->Author )
            && $self->_matchBinding( binding => $self->Binding ) ) {
            return 1;
        }
    }

    # We didn't find a match so clear everything out.
    $self->_clearCache();
}

sub _getSearchResultItems {
    my $self = shift;
    my @nodes;

    my $parser = $self->parentParser();

    my ($noResults) = $parser->look_down( '_tag', 'h1', id => 'noResultsTitle' );

    if ($noResults) {
        Log->notice("No search results found.  Moving on.");
    } else {
        @nodes = $parser->look_down( '_tag', 'td', class => 'searchitem product' );
    }

    return @nodes;
}

sub _clearCache {
    my $self   = shift;
    my $config = $self->_fieldConfig;

    foreach my $key (%$config) {
        $self->{$key} = undef;
    }
}

sub _matchTitle {
    my $self         = shift;
    my %args         = @_;
    my $fetchedTitle = $args{title};

    # Check for a subset match regardless of word order
    my $containSearch = $args{contains};

    assert($fetchedTitle);

    my $book = new BookPub::Catalog::Book( bookID => $self->bookID );

    my $catalogTitle = $book->Title;
    my $catalogSubtitle = $book->Subtitle if ($hasSubtitle);

    Log->info("   Check if fetched title matches catalog title");

    if ( !defined($catalogTitle) ) {
        Log->info("   -- Undetermined title from catalog");
        return;
    }

    my $fetched = new BookPub::Catalog::Book::Title( title => $fetchedTitle );
    my $catalog = new BookPub::Catalog::Book::Title( title => $catalogTitle, subtitle => $catalogSubtitle );
    my $parsed  = new BookPub::Catalog::Book::Title( parse => $fetchedTitle );

    unless ( $fetched->fuzzyMatch( title => $catalog->Title, subtitle => $catalog->Subtitle )
        || $parsed->fuzzyMatch( title => $catalog->Title, subtitle => $catalog->Subtitle )
        || $parsed->titleFuzzyMatch( title => $catalog->Title )
        || ( $containSearch && $fetched->contains( title => $catalog->Title, subtitle => $catalog->Subtitle ) ) ) {
        Log->info( "   -- Title match failed. Fetched: \"" . $fetched->Combined . "\" Catalog: \"" . $catalog->Combined . "\"" );
        return;
    }

    Log->info("   -- Title match success!");
    return 1;
}

sub _matchAuthor {
    my $self   = shift;
    my %args   = @_;
    my $author = $args{author};

    assert($author);

    my $book = new BookPub::Catalog::Book::WithAuthor( bookID => $self->bookID );

    Log->info("   Check if fetched author matches catalog author");

    my $fetched = new BookPub::Catalog::Author($author);
    my $catalog = new BookPub::Catalog::Author( $book->AuthorName );

    if ( !defined( $fetched->Author ) ) {
        Log->info("   -- Undetermined author from request object");
        return;
    }

    if ( !defined( $catalog->Author ) ) {
        Log->info("   -- Undetermined author from catalog");
        return;
    }

    unless ( $fetched->fuzzyMatch( $catalog->Author ) ) {
        Log->info( "   -- Author match failed. Fetched: \"" . $fetched->Author . "\" Catalog: \"" . $catalog->Author . "\"" );
        return;
    }

    Log->info( "Fetched Author: " . $fetched );
    Log->info( "Catalog Author: " . $fetched );

    return 1;
}

# Fail match if "Audible" format.  The kindle store search includes audible books so we want to exclude them.
sub _matchBinding {
    my $self = shift;
    my %args = @_;

    my $binding = $args{binding} || return 1;

    if ( $binding =~ /Audible Audio/i ) {
        Log->info("   -- Audible book found, ignoring it.");
        return;
    }

    return 1;

}

1;
