#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2009 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------
package BookPub::Catalog::Book;
use strict;
use warnings;

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';
use lib '/app/tools/mediaserve/lib';
use BookPub::DB::Item::Book;
use BookPub::DB::Item::BookFormat;
use BookPub::DB::Item::BookProduct;
use BookPub::DB::Item::BookProductImageFile;
use Common::DB::Item::OnixCode;
use BookPub::Catalog::Product::Book::WithPricing;
use Common::RSApp;
use Common::Util;
use Common::Assert;
use Common::FormObject;
use MediaServe::Image::ImageFile;
use BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Availability;

use base 'Common::FormObject';

use constant kDefaultCoverArtWeb => "/production/images/no_book_cover_web.png";

sub _init {
    my ( $self, %args ) = @_;

    $self->SUPER::_init(%args);

    my %properties;
    if ( $args{dbItem} ) {
        $self->_propertiesFromDBItem( \%properties, $args{dbItem} );
    } elsif ( $args{bookID} ) {
        $self->_propertiesFromDB( \%properties, $args{bookID} );
    } else {
        $self->_propertiesFromDefaults( \%properties );
    }

    $self->_initProperties( \%properties );

    return $self;
}

sub _propertiesFromDB {
    my ( $self, $hrProperties, $bookID ) = @_;

    my $dbItem = BookPub::DB::Item::Book->Lookup( book_id => $bookID );

    $self->_propertiesFromDBItem( $hrProperties, $dbItem );
}

sub _propertiesFromDBItem {
    my ( $self, $hrProperties, $dbItem ) = @_;
    assert($dbItem);

    $hrProperties->{book_id} = $dbItem->book_id;

    #	$hrProperties->{imprint_id}     = $dbItem->imprint_id;
    $hrProperties->{title}          = $dbItem->title;
    $hrProperties->{title_clean}    = $dbItem->title_clean;
    $hrProperties->{subtitle}       = $dbItem->subtitle;
    $hrProperties->{subtitle_clean} = $dbItem->subtitle_clean;

    #	$hrProperties->{language_code}  = $dbItem->language_code;
    $hrProperties->{audience_code_id} = $dbItem->audience_code_id;

    #	$hrProperties->{num_pages}      = $dbItem->num_pages;
    #	$hrProperties->{edition}        = $dbItem->edition;

    $hrProperties->{date_created}  = $dbItem->date_created;
    $hrProperties->{date_modified} = $dbItem->date_modified;
    $hrProperties->{created_by}    = $dbItem->created_by;
    $hrProperties->{modified_by}   = $dbItem->modified_by;
}

sub _initProperties {
    my ( $self, $props ) = @_;

    # Not editable...
    #    $self->{BookID}         = Common::FormObject::Scalar->new(value => $props->{book_id}, readOnly => 1);
    $self->{BookID} = $props->{book_id};

    #	$self->{ImprintID}      = Common::FormObject::Scalar->new(value => $props->{imprint_id});

    $self->{Title}         = Common::FormObject::Scalar::String->new( value => $props->{title} );
    $self->{TitleClean}    = Common::FormObject::Scalar::String->new( value => $props->{title_clean}, readOnly => 1 );
    $self->{Subtitle}      = Common::FormObject::Scalar::String->new( value => $props->{subtitle} );
    $self->{SubtitleClean} = Common::FormObject::Scalar::String->new( value => $props->{subtitle_clean}, readOnly => 1 );

    #	$self->{LanguageCode}   = Common::FormObject::Scalar::String->new(value => $props->{language_code});
    $self->{AudienceCodeID} = Common::FormObject::Scalar->new( value => $props->{audience_code_id} );

    #	$self->{NumPages}       = Common::FormObject::Scalar::Integer->new(value => $props->{num_pages});
    #	$self->{Edition}        = Common::FormObject::Scalar::Integer->new(value => $props->{edition});

    $self->{CreatedDate}  = Common::FormObject::Scalar::DateTime->new( value => $props->{date_created},  readOnly => 1 );
    $self->{ModifiedDate} = Common::FormObject::Scalar::DateTime->new( value => $props->{date_modified}, readOnly => 1 );
    $self->{CreatedBy}    = Common::FormObject::Scalar::UserName->new( value => $props->{created_by},    readOnly => 1 );
    $self->{ModifiedBy}   = Common::FormObject::Scalar::UserName->new( value => $props->{modified_by},   readOnly => 1 );

    # Going to stuff the cover art in here as well.
    #
    my $coverArtWeb;

    if ( $props->{book_id} ) {
        $coverArtWeb = $self->_getCoverArtWeb( $props->{book_id} );
    }

    $self->{CoverArtWeb} = $coverArtWeb;

}

sub _getCoverArtWeb {
    my $self = shift;
    my $book_id = shift || die "book id required";
    my $url;

    foreach my $product ( $self->_getProducts($book_id) ) {
        $url = $self->_lookupCoverArt($product);

        last if ($url);
    }

    $url = kDefaultCoverArtWeb unless ($url);
    return $url;
}

sub _getProducts {
    my $self = shift;
    my $book_id = shift || return ();
    my @products;

    my $collection = BookPub::DB::Item::BookProduct->GetAllByBookID($book_id);

    # We want to give priority to the hardback cover art, so we'll move them to the front of the line.
    #
    while ( my $product = $collection->next() ) {

        my $isHardcover = $self->_isHardcover($product);

        if ($isHardcover) {
            unshift( @products, $product->product_id );
        } else {
            push( @products, $product->product_id );
        }
    }

    return @products;
}

sub _isHardcover {
    my $self = shift;
    my $product = shift || return ();

    if ( $product->book_format_id ) {
        my $bookFormat = BookPub::DB::Item::BookFormat->Lookup( book_format_id => $product->book_format_id );
        my $bookFormatType = BookPub::DB::Item::BookFormatType->Lookup( book_format_type_id => $bookFormat->book_format_type_id );
        my $codeItem = Common::DB::Item::OnixCode->Lookup( onix_code_id => $bookFormatType->onix_code_id );
        if ($codeItem) {
            if ( $codeItem->description() eq 'Hardback' ) {
                return 1;
            }
        }
    }

    return undef;
}

sub _lookupCoverArt {
    my $self = shift;
    my $product_id = shift || return;
    my $url;

    my $webFile = BookPub::DB::Item::BookProductImageFile->Lookup(
        book_product_id => $product_id,
        file_type       => 'large',
    );

    my $origFile = BookPub::DB::Item::BookProductImageFile->Lookup(
        book_product_id => $product_id,
        file_type       => 'original',
    );

    if ($webFile) {

        #Common::Log::Debug("FOUND WEB");
        my $image = MediaServe::Image::ImageFile->new( clientID => Common::RSApp::GetClientID(), id => $webFile->media_file_id );
        if ($image) {
            $url = $image->url();
        }
    } elsif ($origFile) {
        Common::Log::Print("DEFAULTING TO ORIGINAL");
        my $image = MediaServe::Image::ImageFile->new( clientID => Common::RSApp::GetClientID(), id => $origFile->media_file_id );
        if ($image) {
            $url = $image->url();
        }
    }

    return $url;
}

sub _propertiesFromDefaults {
    my ( $self, $hrProperties ) = @_;
}

sub save {
    my ($self) = @_;

    my $dbObj = $self->_saveBook();
    $self->_init( dbItem => $dbObj );
}

# jpk - broke this out into an 'inner' method to make it easier to subclass
#
sub _saveBook {
    my ($self) = @_;

    my $bookDBObj;
    if ( $self->BookID() ) {
        $bookDBObj = BookPub::DB::Item::Book->Lookup( book_id => $self->BookID() );
    } else {
        $bookDBObj = BookPub::DB::Item::Book->Create();
    }

    $bookDBObj->title( $self->Title() );
    $bookDBObj->title_clean( Common::Util::clean( $self->TitleClean() ) );
    $bookDBObj->subtitle( $self->Subtitle() );
    $bookDBObj->subtitle_clean( Common::Util::clean( $self->SubtitleClean() ) );

    #    $bookDBObj->imprint_id($self->ImprintID());
    #	$bookDBObj->language_code($self->LanguageCode());
    $bookDBObj->audience_code_id( $self->AudienceCodeID() );

    #	$bookDBObj->num_pages($self->NumPages());
    #	$bookDBObj->edition($self->Edition());
    #	$bookDBObj->volume($self->Volume());

    $bookDBObj->save();

    $self->BookID( $bookDBObj->book_id );

    return $bookDBObj;

}

# Return the max current price for all physical products
sub maxPhysicalCurrentPrice {
    my $self         = shift;
    my %args         = @_;
    my $currencyCode = $args{currency};
    my $serviceID    = $args{serviceID};

    my $maxPrice;

    assert($currencyCode);

    my @products = $self->_getProducts( $self->BookID );

    foreach my $id (@products) {
        my $product = new BookPub::Catalog::Product::Book::WithPricing( productID => $id );
        my $available =
          new BookPub::RDAS::Form::ProductMonitor::ProductMonitorItem::Availability( productID => $id, serviceID => $serviceID )
          if ($serviceID);
        my $price = $product->getPriceByCurrency($currencyCode);

        next if ( $serviceID && ( !$available || !$available->Availability || $available->Availability ne 'available' ) );

        if ( defined($price) && !$product->isEBook() ) {
            $maxPrice = $price->Price() if ( !defined($maxPrice) || $price->Price() > $maxPrice );
        }
    }

    return $maxPrice;
}

###
1;    #
###
