#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2010 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------
package BookPub::Price::DefaultPrice;
use strict;
use warnings;
use Data::Dumper;

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';
use BookPub::DB::Item::ProductMarketPrice;
use Common::RSApp;
use Common::Util;
use Common::Assert;
use Common::FormObject;
use Common::CurrencyFormat;

use BookPub::Price::ProductMarketPrice;
use BookPub::DB::Item::Region;
use BookPub::DB::Item::ProductMarket;

use base 'Common::FormObject';

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

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

    assert( $args{productID} );

    $self->_initProperties( \%args );

    return $self;
}

sub _initProperties {
    my $self  = shift;
    my $props = shift;

    my $country = $self->_defaultCountry();

    $self->{Country} = $country if ($country);
    $self->{Currency} = Common::CurrencyFormat->new( countryCode => $self->Country )
      if ($country);

    $self->_initFromProductID( $props->{productID} );

    return $self;
}

sub _initFromProductID {
    my $self      = shift;
    my $productID = shift || return;
    my $currency  = $self->{Currency}->currencyCode() if ( $self->{Currency} );

    return unless ( $self->{Country} );

    # !!! This whole algorithm is broken.
    # !!! We can't assume one market per country.
    # !!! Going to need to find another way to determine what the default price is.
    #
    # So it seems like we need to turn this around.   We can get all the ProductMarketPrices for this
    # product first, then see which of those are in markets that include this country.
    # HOPEFULLY, there will just be 1...
    # !!! Which is great and everything, but I did not do it that way.  Duh.
    #
    # !!! So, the issue is with clients (BloomsburyUSA), where everything is in the same 'global' market,
    # !!! and there are regions associated with every _price_.
    #
    # !!! I suppose I can keep this current scheme, but when I run into more than one product market, I will
    # !!! then need to descend into the actual prices, and see which of these are in the correct country.
    #

    # First, fetch all the product markets for this product in any of the regions that contain the Country.
    #
    my @regions = $self->_getRegionsByCountry( $self->{Country} );
    my $allProductMarkets = BookPub::DB::Item::ProductMarket->GetAllByRegion( product_id => $productID, region_id => \@regions );

    # How many are there, I wonders?
    #
    my $matchingProductMarket;
    if ( $allProductMarkets->size() > 1 ) {

        # Looks like this client has 'generic' regions (or their data is wacky).
        # So see if we can find regions in their actual prices.
        #
        my $winningPrice;
        my @productMarketIDs;
        my %productMarketHash;
        while ( my $productMarket = $allProductMarkets->next() ) {
            $productMarketHash{ $productMarket->product_market_id() } = $productMarket;
            push @productMarketIDs, $productMarket->product_market_id();
        }

        my @matchingProductMarketIDs = BookPub::DB::Item::ProductMarketPrice->GetProductMarketIDsThatIntersectTheseRegions(
            productMarketID => \@productMarketIDs,
            regionID        => \@regions,
            currencyCode    => $currency,
        );

        # Let's just return the first one.
        if ( scalar @matchingProductMarketIDs > 0 ) {
            $matchingProductMarket = $productMarketHash{ $matchingProductMarketIDs[0] };
        }

        # JPK - The correct answer might be 'none'...
        #
        #if (scalar @matchingProductMarketIDs > 1)
        #{
        #    die "ERROR - unable to unambiguously determine correct product market for product $productID, country " . #$self->{Country}
        #     . "\nproductMarketID array: " . Dumper(\@productMarketIDs)
        #     . "\nregionID array: " . Dumper(\@regions)
        #     . "\nmatchingProductMarketIDs: " . Dumper(\@matchingProductMarketIDs)
        #     . "\ncurrencyCode: " . $currency;
        #}
        #elsif (scalar @matchingProductMarketIDs == 1)
        #{
        #    $matchingProductMarket = $productMarketHash{$matchingProductMarketIDs[0]};
        #}
    } else {
        $matchingProductMarket = $allProductMarkets->next();
    }

    if ($matchingProductMarket) {
        $self->{MarketID} = $matchingProductMarket->market_id();
    }
}

sub _getRegionsByCountry {
    my $self = shift;
    my $country = shift || return;
    my @results;

    my $collection = BookPub::DB::Item::Region->GetAllRegions( country_code => $country );

    while ( my $row = $collection->next() ) {
        push( @results, $row->region_id );
    }

    return @results;
}

sub _getMarketID {
    my $self    = shift;
    my @regions = @_;

    my $collection = BookPub::DB::Item::Market->GetAllByRegionIDs(@regions);

    # This will fail if we have more then 1 supplier in a market.  Currently the
    # database supports this, but we've been assured that this will never be the
    # case.  If it does happen then we will need to use supplier id as criteria
    # to find market id.
    #
    # !!! This is not going to fly anymore.  Faber and Faber, for example, have a _dozen_
    # !!! regions that include GB.  So there's a shit-ton of markets.
    #
    assert( $collection->size() <= 1 );

    return $collection->hasNext ? $collection->next()->market_id : undef;
}

###
1;    #
###
