#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2009 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#---------------------------------------------------------------
package BookPub::Catalog::GroupedBookProducts;
use strict;
use warnings;
use Data::Dumper;
use Scalar::Util qw(blessed);

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';
use Common::RSApp;
use Common::Util;
use Common::Assert;
use Common::FormObject;

use base 'Common::XMLObject';

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

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

    if ( $args{bookProductList} ) {
        $self->{BookProductList} = $self->_organizeBookProductList( $args{bookProductList} );
    }

    return $self;
}

sub _organizeBookProductList {
    my ( $self, $bookProductList ) = @_;

    return undef unless $bookProductList;

    # Digging out the pricing data is frankly annoying and expensive.
    # I don't want to have to do that twice.
    # So, I'm going to iterate over the book products and hash them into
    # buckets, based on format and price (if eBook).
    #
    # I'll then sort each bucket separately, based on descriptions.
    #

    my %bucketOrder = (
        'BB' => 1,
        'BC' => 2,
        'DG' => 4,
        'AJ' => 5,
        'AC' => 5,
        'AA' => 5,
    );

    my $origBookProductArrayRef = $bookProductList->{BookProduct};
    my %buckets;
    foreach my $bookProduct ( @{$origBookProductArrayRef} ) {
        my $formatCode        = $bookProduct->{ProductFormat}{BookFormatType}{Code};
        my $formatDescription = $bookProduct->{ProductFormat}{BookFormatType}{Description};

        # All 'other' formats end up in the last, catch-all bucket.
        #
        my $bucketID = $bucketOrder{$formatCode};
        if ( !$bucketID ) {
            $bucketID          = 6;
            $formatDescription = 'Other';
        }

        # There are going to be two different eBook buckets - One for Agency products, and one for RRP products.
        # We have to examine each product's pricing data to determine where it goes.
        #
        if ( 'DG' eq $formatCode ) {
            my $pricing = $self->_getPricing($bookProduct);
            my $priceTypeID = $self->_priceTypeID($pricing);
            if ( defined $priceTypeID && ( 41 == $priceTypeID || 42 == $priceTypeID ) ) {
                $formatDescription = $formatDescription . ' (Agency)';
                $bucketID          = 3;
            }
        }

        if ( 5 == $bucketID ) {
            $formatDescription = 'Audio';
        }

        if ( !$buckets{$bucketID} ) {
            $buckets{$bucketID} = {
                Description => $formatDescription,
                BookProduct => [],
            };
        }
        push @{ $buckets{$bucketID}{BookProduct} }, $bookProduct;
    }

    # Great, we have buckets.
    # Now sort them, and push the buckets onto another array in the order desired (by those who care about this).
    #
    my @bucketList;
    for ( my $i = 1 ; $i <= 6 ; $i++ ) {
        my $bucket = $buckets{$i};
        if ($bucket) {
            @{ $bucket->{BookProduct} } = sort { $self->_sortByDescription( $a, $b ) } @{ $bucket->{BookProduct} };
            push @bucketList, $bucket;
        }
    }

    return \@bucketList;
}

sub _sortByDescription {
    my ( $self, $itemA, $itemB ) = @_;

    my $aFormat = $itemA->{ProductFormat};
    my $bFormat = $itemB->{ProductFormat};

    my $sortValueA;
    my $sortValueB;

    if ( $aFormat->{BookFormatSubtype} ) {
        $sortValueA = $aFormat->{BookFormatSubtype}{Description};
    } else {
        $sortValueA = $aFormat->{BookFormatType}{Description};
    }

    if ( $bFormat->{BookFormatSubtype} ) {
        $sortValueB = $bFormat->{BookFormatSubtype}{Description};
    } else {
        $sortValueB = $bFormat->{BookFormatType}{Description};
    }

    return lc($sortValueA) cmp lc($sortValueB);
}

sub _getPricing {
    my ( $self, $bookProduct ) = @_;

    assert($bookProduct);

    my $primaryMarketID       = $bookProduct->{DefaultPrimary}{MarketID};
    my $primaryMarketCurrency = $bookProduct->{DefaultPrimary}{Currency}{CurrencyCode};
    my $pricingArray          = $bookProduct->{Pricing};

    foreach my $pricingData (@$pricingArray) {
        my $market = $pricingData->{Market};

        my $marketID = $self->_marketID($market);
        next unless defined $marketID && $marketID == $primaryMarketID;

        my $currencyArray = $market->{Currency};
        foreach my $currency (@$currencyArray) {
            my $priceArray = $currency->{Prices}{ProductMarketPrice};
            foreach my $pmp (@$priceArray) {
                my $currencyCode = $self->_currencyCode($pmp);
                if ( defined $currencyCode && $currencyCode eq $primaryMarketCurrency ) {
                    return $pmp;
                }
            }
        }
    }

    return undef;
}

sub _marketID {
    my ( $self, $market ) = @_;

    return undef unless $market;

    if ( blessed($market) && $market->can('MarketID') ) {
        return $market->MarketID();
    }

    return $market->{MarketID};
}

sub _currencyCode {
    my ( $self, $price ) = @_;

    return undef unless $price;

    if ( blessed($price) && $price->can('CurrencyCode') ) {
        return $price->CurrencyCode();
    }

    return $price->{CurrencyCode};
}

sub _priceTypeID {
    my ( $self, $price ) = @_;

    return undef unless $price;

    if ( blessed($price) && $price->can('PriceTypeID') ) {
        return $price->PriceTypeID();
    }

    return $price->{PriceTypeID};
}

###
1;    #
###
