#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package BookPub::Tracker::Command::Main;
use strict;
use warnings;
use Data::Dumper;
use POSIX;

use lib '/app/tools/common/lib';
use RSApache::Response::XSLT;
use Common::Preference;
use Common::Assert;
use Common::Util;
use Common::Log;

use lib '/app/tools/bookpub/lib';
use BookPub::Tracker::Period;
use BookPub::DB::Item::Period;
use BookPub::DB::Item::ReportConfig;
use BookPub::Tracker::FileList::OnHoldFiles;
use BookPub::Tracker::FileList::OpenFiles;
use BookPub::Tracker::FileList::NewFiles;
use BookPub::Tracker::FileList::ClosedFiles;
use BookPub::Sale::Report::Royalty::Configurable;
use BookPub::Sale::Report::Reconciliation;
use BookPub::Sale::Report::Exceptions::AllFiles;
use BookPub::Sale::Report::PriceExceptions::AllFiles;

use base 'BookPub::Command';

sub cmd      { return "main"; }
sub area     { return "tracker"; }
sub pageName { return 'Revenue File Tracker'; }

use constant kTemplate => '/app/tools/bookpub/templates/tracker/main.xsl';

# !!! I am going to _abandon_ the old 'base command' stuff.
# !!! I would rather rebuild this from the top-down

use constant kCookieFileType      => 'bookpub_tracker_main_fileType';
use constant kCookiePageSize      => 'bookpub_tracker_main_pageSize';
use constant kCookieSortBy        => 'bookpub_tracker_main_sortBy';
use constant kCookieReverseSort   => 'bookpub_tracker_main_reverseSort';
use constant kCookieServiceFilter => 'bookpub_tracker_main_serviceFilter';

use constant kDefaultFileType    => 1;
use constant kDefaultPageSize    => 25;
use constant kDefaultSortBy      => 'service_name';
use constant kDefaultServiceID   => 0;
use constant kDefaultReverseSort => 0;

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

    # Give any inherited methods the first crack at this.
    # (This checks for login and basic access permissions).
    #
    my $response = $self->SUPER::execute();
    return $response if $response;

    my @rejectedFiles;
    my $rejectedFiles = $self->getParam('rejected');
    if ($rejectedFiles) {
        my @rejectedArray = split( /\|\|/, $rejectedFiles );
        foreach my $rejectedFile (@rejectedArray) {
            my %rejectedHash;
            my @rejectedSplit = split( /\|/, $rejectedFile );
            $rejectedHash{FileName} = $rejectedSplit[1];
            $rejectedHash{Code}     = $rejectedSplit[2];
            push @rejectedFiles, \%rejectedHash;
        }
        $self->{xml}{RejectedFiles}{RejectedFile} = \@rejectedFiles;
    }

    # !!! NOTE - The current tracker page uses a cookie for fileType,pageSize,sortBy,reverseSort.
    # !!! We'll probably want to use the newer Preferences interface for this stuff.
    # !!! Other things, like the current page, come in as cgi parameters.
    #
    my $fileType =
      Common::Util::returnFirstDefined( $self->getParam('fileType'), Common::Preference::GetValue(kCookieFileType), kDefaultFileType );
    my $serviceSelected = Common::Util::returnFirstDefined(
        $self->getParam('serviceID'),
        Common::Preference::GetValue(kCookieServiceFilter),
        kDefaultServiceID
    );
    my $pageSize =
      Common::Util::returnFirstDefined( $self->getParam('pageSize'), Common::Preference::GetValue(kCookiePageSize), kDefaultPageSize );

    # check the cookied sortBy(if any) against what's in the params (if any) to see
    # if we need to flip the sort direction
    my $sortByCookie = Common::Preference::GetValue(kCookieSortBy);
    my $sortBy       = $self->getParam('sortBy');

    my $reverseSortCookie = Common::Preference::GetValue(kCookieReverseSort);
    my $reverseSort;

    if ( $sortByCookie && $sortByCookie eq $sortBy ) {

        # toggle the sort direction
        $reverseSort = $reverseSortCookie ? 0 : 1;
        $sortBy = $sortByCookie;
    }
    $reverseSort = Common::Util::returnFirstDefined( $reverseSort, $reverseSortCookie, kDefaultReverseSort );
    $sortBy      = Common::Util::returnFirstDefined( $sortBy,      $sortByCookie,      kDefaultSortBy );

    my $page = $self->getParam('page');
    $page = 1 unless $page;

    # Some of the templates want to know what page we're on.
    #
    $self->{xml}{Pagination}{CurrentPage} = $page;

    # Instantiate the Period object.
    # !!! This will probably also tell us the prev/next period ids, for navigation.
    #
    my $periodID = $self->getParam('period');
    $periodID = 0 unless $periodID;

    my $period = BookPub::Tracker::Period->new( periodID => $periodID );
    $self->{xml}{Period} = $period;

    # Get the list of files.
    # !!! This is paginated, right?   So we'll need to pass that along to the FileList object.
    #
    # !!! Let's use discreet classes for each type of file, rather than one mondo FileList object.
    $self->{xml}{Files}{NewFiles} = BookPub::Tracker::FileList::NewFiles->new( periodID => $periodID );
    $self->{xml}{Files}{OnHoldFiles} = BookPub::Tracker::FileList::OnHoldFiles->new( periodID => $periodID );
    $self->{xml}{Files}{ClosedFiles} = BookPub::Tracker::FileList::ClosedFiles->new( periodID => $periodID );

    # Report the values for the OpenFile section parameters to the template.
    #
    $self->{xml}{OpenFileSettings}{FileType}    = $fileType;
    $self->{xml}{OpenFileSettings}{PageSize}    = $pageSize;
    $self->{xml}{OpenFileSettings}{ServiceID}   = $serviceSelected;
    $self->{xml}{OpenFileSettings}{SortBy}      = $sortBy;
    $self->{xml}{OpenFileSettings}{ReverseSort} = $reverseSort;

    my @services;
    my $includesServiceSelected = 0;
    my $allServices = BookPub::Tracker::Service::GetAllServiceNamesInPeriod( periodID => $periodID );
    while ( my $service = $allServices->next() ) {
        my %serviceHash;
        $serviceHash{serviceName} = $service->service_name;
        $serviceHash{serviceID}   = $service->service_id;

        # Setting a flag so that we'll know if the selected service actually has
        # any open files left.
        if ( $service->service_id == $serviceSelected ) {
            $includesServiceSelected = 1;
        }

        push @services, \%serviceHash;
    }
    $self->{xml}{OpenFileSettings}{ServiceList}{Service} = \@services;

    if ( $includesServiceSelected == 0 && $periodID == 0 ) {
        $serviceSelected = 0;
    }

    $self->{xml}{Files}{OpenFiles} = BookPub::Tracker::FileList::OpenFiles->new(
        periodID    => $periodID,
        page        => $page || 1,
        pageSize    => $pageSize ne 'all' ? $pageSize : 999,
        serviceID   => $serviceSelected,
        fileType    => $fileType,
        sortBy      => $sortBy,
        reverseSort => $reverseSort,
    );

    # And we want to see which reports are available.
    #
    #royalty
    #royalty_excel
    #reconciliation

    # Check if the royalty report has been generated
    my $oPeriod = BookPub::DB::Item::Period->Lookup( period_id => $periodID );
    $self->{xml}{Report}{Royalty}{Status} = $oPeriod->royalty_report_created if $oPeriod;

    my $reconReport = BookPub::Sale::Report::Reconciliation->new( periodID => $periodID );
    $self->{xml}{Report}{Reconciliation}{Status} = 1 if ( -f $reconReport->filePath() );

    if ( !$periodID ) {

        # Check for generated exceptions report.
        my $exceptionReport = BookPub::Sale::Report::Exceptions::AllFiles->new();
        my $path            = $exceptionReport->filePath();
        my $status          = 0;
        $status = 1 if ( -f "$path-tmp" );
        $status = 2 if ( -f $path );
        $self->{xml}{Report}{Exceptions}{Status} = $status;

        if ( $status == 2 ) {

            # Going to use the last modified date as the generation time for the exceptions report.
            my $epoch_timestamp = ( stat($path) )[9];
            my $timestamp = $epoch_timestamp;

            $self->{xml}{Report}{Exceptions}{DateGenerated} = $timestamp;
        }

        # Now check for generated price exceptions report.
        my $priceExceptionReport = BookPub::Sale::Report::PriceExceptions::AllFiles->new();
        my $pricePath            = $priceExceptionReport->filePath();
        my $priceStatus          = 0;
        $priceStatus = 1 if ( -f "$pricePath-tmp" );
        $priceStatus = 2 if ( -f $pricePath );
        $self->{xml}{Report}{PriceExceptions}{Status} = $priceStatus;

        if ( $priceStatus == 2 ) {

            # Going to use the last modified date as the generation time for the exceptions report.
            my $epoch_timestamp = ( stat($pricePath) )[9];
            my $timestamp = $epoch_timestamp;

            $self->{xml}{Report}{PriceExceptions}{DateGenerated} = $timestamp;
        }

    }

    # Write out the sorting params as cookies.
    #
    Common::Preference::SetPersistentCookie( kCookieFileType,      $fileType );
    Common::Preference::SetPersistentCookie( kCookiePageSize,      $pageSize );
    Common::Preference::SetPersistentCookie( kCookieSortBy,        $sortBy );
    Common::Preference::SetPersistentCookie( kCookieReverseSort,   $reverseSort );
    Common::Preference::SetPersistentCookie( kCookieServiceFilter, $serviceSelected );
    Common::Preference::StoreCookies();

    $response = RSApache::Response::XSLT->new( $self->{xml}, kTemplate );

    return $response;
}

1;
