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

use IO::File;
use File::Path;

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::Client;
use Common::Email;
use Common::RSApp;
use Common::Util;

use lib '/app/tools/bookpub/lib';
use BookPub::Config;
use BookPub::DB::Item::Period;
use BookPub::DB::Item::Service;

use base 'BookPub::Sale::Report';

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

    assert( 0, 'override to return package name for row class' );
}

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

    assert( 0, 'override to return seperator character (for text file version)' );

}

sub fileName {
    my ($self) = @_;
    if ( !$self->{_fileName} ) {
        my $client    = Common::Client::Current();
        my $period    = BookPub::DB::Item::Period->Lookup( period_id => $self->{_periodID} );
        my $periodRef = $period->name();
        $periodRef =~ s/\s+/_/g;
        $periodRef =~ s/\W+//g;
        $periodRef ||= $period->period_id();

        $self->{_fileName} = $client->ClientNameClean() . "_RoyaltyReport_$periodRef.tsv";
    }
    return $self->{_fileName};
}

sub excelFileName {
    my ($self) = @_;
    assert( 0, 'override' );
}

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

    if ( !$self->{_excelFilePath} ) {
        my $baseDir = $self->_baseDir();
        $self->{_excelFilePath} = $baseDir . '/' . $self->excelFileName();
    }
    return $self->{_excelFilePath};
}

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

    assert( 0, 'override' );
}

sub _sendErrorEmail {
    my ( $self, $error ) = @_;

    if (Common::RSApp::IsProductionServer) {
        # send an email about the error
        my $emailFrom   = 'do-not-reply@royaltyshare.com';
        my $reportEmail = Common::RSApp::GetConfig( 'bookpub', 'error_report_email' );

        my $subject = "Error - Output file failed";
        my $body    = "Output file failed to generate\n\n";
        $body .= $error . "\n\n";

        my $client = new Common::Client( clientID => Common::RSApp::GetClientID() );
        my $name = $client->ClientName || "Client ID: " . Common::RSApp::GetClientID();
        $subject .= ' for Period ID ' . $self->periodID() . ' (' . $name . ')';

        Common::Email->SendAWS(
            from    => $emailFrom,
            to      => $reportEmail,
            subject => $subject,
            body    => $body
        );
    } else {
        print STDERR "$error\n";
    }
}

sub _getReportingPeriod {
    my ( $self, $fileID ) = @_;

    # Get the date range
    my ( $dateBegin, $dateEnd ) = BookPub::DB::Item::Sale->GetDateRangeByFileID($fileID);

    # Compare the dates to determing the reporting period
    my ( $reportingMonth, $reportingQuarter, $reportingYear ) = $self->_compareSalesMonths( $dateBegin, $dateEnd );

    if ( !$reportingMonth && !$reportingQuarter ) {

        # If that didn't work, normalize the date range
        my ( $dateBeginNormal, $dateEndNormal ) = Common::Util::normalize_sales_month_dates( $dateBegin, $dateEnd );

        # And try again.
        ( $reportingMonth, $reportingQuarter, $reportingYear ) = $self->_compareSalesMonths( $dateBeginNormal, $dateEndNormal );
    }

    if ( !$reportingMonth && !$reportingQuarter ) {

        # We've got some files that have sales outside of the reporting period range.
        # So, we'll try a different approach so that we can hopefully ignore those outlying sales.
        my $dateBeginNormal = BookPub::DB::Item::Sale->GetNormalizedBeginMonthByFileID($fileID);
        my $dateEndNormal   = BookPub::DB::Item::Sale->GetNormalizedEndMonthByFileID($fileID);

        ( $reportingMonth, $reportingQuarter, $reportingYear ) = $self->_compareSalesMonths( $dateBeginNormal, $dateEndNormal );
    }

    # If we still don't have these, time to die.
    if ( !$reportingMonth && !$reportingQuarter ) {

        # !!! Actually, we'll let the new validation code handle this so that it can be bundled with other errors.
        # We'll just send nothing back.
        return undef;

        #my $error = "Unable to determine reporting period for file ID: " . $fileID;
        #$self->_sendErrorEmail($error);
        #die $error . "\n";
    }

    return ( $reportingMonth, $reportingQuarter, $reportingYear );
}

sub _compareSalesMonths {
    my ( $self, $dateBeginNormal, $dateEndNormal ) = @_;

    my ( $reportingMonth, $reportingQuarter, $reportingYear );

    my $dateBeginMonth = substr( $dateBeginNormal, 5, 2 );
    my $dateEndMonth   = substr( $dateEndNormal,   5, 2 );

    # If these fall in the same month, it's a monthly file.
    if ( $dateBeginMonth == $dateEndMonth ) {
        $reportingMonth = $dateBeginMonth;
        $reportingYear = substr( $dateBeginNormal, 0, 4 );
    }

    # If not, then we should be dealing with a quarterly file
    elsif (
        ( $dateEndMonth - $dateBeginMonth == 2 )
        && (   $dateBeginMonth == 1
            || $dateBeginMonth == 4
            || $dateBeginMonth == 7
            || $dateBeginMonth == 10 )
      ) {
        $reportingQuarter = '0' . $dateEndMonth / 3;
        $reportingYear = substr( $dateBeginNormal, 0, 4 );
    }

    return ( $reportingMonth, $reportingQuarter, $reportingYear );
}

# !!! Deprecating this at this level.  In the Real World, we have way too much
# variability on how these reports are structured to assume a single header followed
# by a bunch of sale lines.
# So each subclass will need to implement this.
#
sub create {
    my ($self) = @_;
    assert( 0, 'override this' );
}

sub createExcel {
}

###
1;    #
###
