#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2011 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#---------------------------------------------------------------
package BookPub::Catalog::Import::Process::Analyzer::HachetteUK;
use strict;
use warnings;
use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::Assert;

use lib '/app/tools/bookpub/lib';
use base 'BookPub::Catalog::Import::Process::Analyzer::Base';

# We're overloading this for HUk so that we can take book format into consideration
# when validating the book product.

sub _validateBookProduct {
    my ( $self, $bookProduct ) = @_;
    $self->_report( "_validateBookProduct:", 3 );
    $self->_report( $bookProduct,            4 );

    # Should we validate the book first?
    # This will allow us to determine the original book id.
    #
    my $stagedBook = BookPub::DB::Item::CatalogImportItem::Book->Lookup( catalog_import_book_id => $bookProduct->catalog_import_book_id );
    $self->_validateBook($stagedBook);

    #    $stagedBook = BookPub::DB::Item::CatalogImportItem::Book->Lookup(catalog_import_book_id => $bookProduct->catalog_import_book_id);

    # Validate the imprint next.
    # We'll want to determine the live id.
    #
    my $stagedImprint =
      BookPub::DB::Item::CatalogImportItem::Imprint->Lookup( catalog_import_imprint_id => $bookProduct->catalog_import_imprint_id );
    $self->_validateImprint($stagedImprint);

    my $stagedPublisher =
      BookPub::DB::Item::CatalogImportItem::Publisher->Lookup( catalog_import_publisher_id => $bookProduct->catalog_import_publisher_id );
    $self->_validatePublisher($stagedPublisher);

    # Validate the book_product_contributors
    # !!! What we really want to validate is the underlying 'contributor'.
    # !!! We're always going to re-build the book_product_contributor table after every import, since
    # !!! it's just a linking table.
    #
    my $bookProductContributors = BookPub::DB::Item::CatalogImportItem::BookProductContributor->GetAllByProductIDCatalogImportID(
        $bookProduct->catalog_import_product_id(),
        $self->_catalogImportID(),
    );
    while ( my $bookProductContributor = $bookProductContributors->next() ) {
        $self->_report( "bookProductContributor", 4 );
        $self->_report( $bookProductContributor,  4 );
        my $contributor = $self->_validateContributor( $bookProductContributor->catalog_import_contributor_id() );

        # I don't think I really care if a contributor is 'new' or not.  That doesn't really effect the state of the book_contributor.
    }

    # We'll be validating the 'product' record as well.
    #
    my $stagedProduct =
      BookPub::DB::Item::CatalogImportItem::Product->Lookup( catalog_import_product_id => $bookProduct->catalog_import_product_id );

    # Find, if possible, the live version of this book_product.
    #
    $self->_report( "   looking up live book product using both isbn values", 4 );
    my %args;
    $args{isbn10} = $bookProduct->isbn10() if $bookProduct->isbn10();
    $args{isbn13} = $bookProduct->isbn13() if $bookProduct->isbn13();
    $args{book_format_id} = $bookProduct->book_format_id();
    my $liveProduct = BookPub::DB::Item::BookProduct->Lookup(%args);
    $self->_report( $liveProduct, 4 );

    if ( !$liveProduct && ( $bookProduct->isbn10() && $bookProduct->isbn13() ) ) {

        # Perhaps one of the ISBN codes changed?
        #
        my $possibleLiveProducts = BookPub::DB::Item::BookProduct->GetAllWithEitherISBN( $bookProduct->isbn10, $bookProduct->isbn13 );
        while ( my $possibleLiveProduct = $possibleLiveProducts->next() ) {
            $self->_report( "  possible live book product:", 4 );
            $self->_report( $possibleLiveProduct,            4 );

            my $possibleLiveBook = BookPub::DB::Item::Book->Lookup( book_id => $possibleLiveProduct->book_id() );
            $self->_report( "   possible live book:", 4 );
            $self->_report( $possibleLiveBook,        4 );

            # so... if the titles and book format are the same, we'll call this the right product.
            #
            no warnings;
            if (   $stagedBook->title() eq $possibleLiveBook->title()
                && $stagedBook->subtitle() eq $possibleLiveBook->subtitle()
                && $bookProduct->book_format_id() == $possibleLiveProduct->book_format_id() ) {
                $liveProduct = $possibleLiveProduct;
                last;
            } else {
                $self->_report( "!!! the live book didn't match, so we're not using that product...", 4 );
            }
        }
    }

    if ( !$liveProduct && $bookProduct->isbn13() ) {

        # We'll look for exact matches on ISBN13, and then do some fuzzy matching on title.
        #
        my $possibleLiveProducts = BookPub::DB::Item::BookProduct->GetAllByISBN13( $bookProduct->isbn13 );
        while ( my $possibleLiveProduct = $possibleLiveProducts->next() ) {

            # If the formats don't match, then we can't use this one.
            if ( $bookProduct->book_format_id() != $possibleLiveProduct->book_format_id() ) {
                next;
            }

            $self->_report( "  possible live book product:", 4 );
            $self->_report( $possibleLiveProduct,            4 );

            my $possibleLiveBook = BookPub::DB::Item::Book->Lookup( book_id => $possibleLiveProduct->book_id() );
            $self->_report( "   possible live book:", 4 );
            $self->_report( $possibleLiveBook,        4 );

            # If the titles are close, then that's good enough.
            # What seems to be happening a lot is subtitle or edition are being included in the title.
            # So if the ISBN13 matches and of the titles contains the other, this should be the right product.
            no warnings;

            my $stagedTitle   = $stagedBook->title();
            my $possibleTitle = $possibleLiveBook->title();

            if (   $stagedTitle =~ /$possibleTitle/i
                || $possibleTitle =~ /$stagedTitle/i ) {
                $liveProduct = $possibleLiveProduct;
                last;
            } else {
                $self->_report( "!!! the live book didn't match, so we're not using that product...", 4 );
            }
        }

    }

    if ( !$liveProduct ) {

        # This is a new product.
        #
        $self->_report( "  flagging staged book product as new", 4 );

        $bookProduct->import_status(BookPub::DB::Item::CatalogImport::kNew);
        $stagedProduct->import_status(BookPub::DB::Item::CatalogImport::kNew);
        $bookProduct->save();
        $stagedProduct->save();
    } else {

        # We're either updating this product, or leaving it alone.
        #
        # So, we'll compare them and see.
        #
        no warnings;
        if (   $bookProduct->book_format_id() != $liveProduct->book_format_id()
            || $bookProduct->onix_code_publishing_status() ne $liveProduct->onix_code_publishing_status()
            || $bookProduct->language_code() ne $liveProduct->language_code()
            || $bookProduct->num_pages() != $liveProduct->num_pages()
            || $bookProduct->edition() != $liveProduct->edition()
            || $bookProduct->publication_country() ne $liveProduct->publication_country()
            || $stagedImprint->original_imprint_id() != $liveProduct->imprint_id()
            || $stagedPublisher->original_publisher_id() != $liveProduct->publisher_id()
            || $stagedBook->original_book_id() != $liveProduct->book_id()
            || $bookProduct->isbn10() ne $liveProduct->isbn10()
            || $bookProduct->isbn13() ne $liveProduct->isbn13() ) {
            $self->_report( "  flagging staged book product as an update", 4 );

            # !!! Changing these fields _might_ invalidate matches...
            #
            $bookProduct->original_book_id( $stagedBook->original_book_id() );
            $bookProduct->import_status(BookPub::DB::Item::CatalogImport::kUpdate);
            $stagedProduct->import_status(BookPub::DB::Item::CatalogImport::kUpdate);
        } else {
            $self->_report( "  flagging staged book product as unchanged", 4 );
            $bookProduct->import_status(BookPub::DB::Item::CatalogImport::kUnchanged);
            $stagedProduct->import_status(BookPub::DB::Item::CatalogImport::kUnchanged);
        }
        $bookProduct->original_product_id( $liveProduct->product_id() );
        $stagedProduct->original_product_id( $liveProduct->product_id() );

        $bookProduct->save();
        $stagedProduct->save();
    }
}

###
1;    #
###

