package Raptor::Tracker::LicenseIncomeFile;

use strict;
use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::FormObject;
use Common::Assert;
use Common::DB::Item;
use Common::Util;

use lib '/app/tools/raptor/lib';
use Raptor::DB::Item::File;
use Raptor::DB::Item::Sale;
use Raptor::Tracker::LicenseIncomeHash;

use base 'Common::FormObject';

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

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

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

    $self->_initProperties( \%properties );

    return $self;
}

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

    my $dbItem = Raptor::DB::Item::File->Lookup( file_id => $id );
    assert($dbItem);
    assert( $dbItem->type_id() == Raptor::DB::Item::File::kFileTypeLicenseIncome, "ERROR - file $id is not a license income file" );

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

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

    $hrProperties->{file_id}        = $dbItem->file_id;
    $hrProperties->{orig_file_name} = $dbItem->orig_file_name;

    $hrProperties->{period_id}   = $dbItem->period_id;
    $hrProperties->{file_status} = $dbItem->file_status;

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

}

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

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

    $self->{FileID} = Common::FormObject::Scalar->new( value => $props->{file_id}, readOnly => 1 );
    $self->{OrigFileName} = Common::FormObject::Scalar::String->new( value => $props->{orig_file_name}, required => 1 );

    $self->{PeriodID}   = Common::FormObject::Scalar->new( value => $props->{period_id},   readOnly => 1 );
    $self->{FileStatus} = Common::FormObject::Scalar->new( value => $props->{file_status}, readOnly => 1 );

    $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->{LicenseIncomeList} = Raptor::Tracker::LicenseIncomeHash->new( fileID => $props->{file_id} );
}

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

    my $valid = $self->SUPER::validate(%args);
    if ($valid) {
        $self->{LicenseIncomeList}->validate(%args);
    }

    return $valid;
}

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

    # First, I create the actual file entity.
    #
    my $fileDBItem;
    my $fileID = $self->FileID();
    if ($fileID) {
        $fileDBItem = Raptor::DB::Item::File->Lookup( file_id => $fileID );
    } else {
        $fileDBItem = Raptor::DB::Item::File->Create();

        # Make sure we're using the correct native currency.
        #
        my $nativeCurrency = Common::Client::Current()->Locale()->currencyFormat()->currencyCode();
        $fileDBItem->currency_code($nativeCurrency);

        # These virtual files have fewer valid states...
        # They will be either open or closed (well, maybe invalid, too)
        #
        $fileDBItem->file_status(Raptor::DB::Item::File::STATUS_OPEN);
    }

    # We want sales from this file to be classified as 'physical' as far as
    # our billing is concerned...
    #
    $fileDBItem->physical(1);

    $fileDBItem->orig_file_name( $self->OrigFileName );
    $fileDBItem->type_id(Raptor::DB::Item::File::kFileTypeLicenseIncome);
    $fileDBItem->save();

    $fileID = $fileDBItem->file_id;

    # We're going to want to know the total units and revenue amount...
    #
    $self->{LicenseIncomeList}->save( fileID => $fileID );

    my ( $units, $revenue ) = $self->{LicenseIncomeList}->getUnitsAndRevenue();
    $units   = '0'    unless $units;
    $revenue = '0.00' unless $revenue;

    $fileDBItem->records( $self->{LicenseIncomeList}->size() );
    $fileDBItem->units($units);
    $fileDBItem->revenue($revenue);
    $fileDBItem->save();

    return $self->_init( _dbItem => $fileDBItem );
}

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

    # Assumptions:  The file is open, in an open period.
    #
    my $fileID = $self->FileID();
    assert( $fileID, "ERROR - cannot finish a file that has no file_id" );

    my $dbItem = Raptor::DB::Item::File->Lookup( file_id => $fileID );
    assert( $dbItem, "ERROR - invalid file_id $fileID" );

    assert( 0 == $self->{period_id}, "ERROR - cannot finish a file in a closed period" );
    assert( Raptor::DB::Item::File::STATUS_OPEN == $dbItem->file_status,
        "ERROR - cannot finish a file that is not OPEN: file_id $fileID, status = " . $dbItem->file_status );

    # And, no point in finishing a file with no records...
    #
    assert( 0 < $self->{LicenseIncomeList}->size(), 'ERROR - cannot finish a file with no income' );

    # So, in this step, we'll create entries in the Sale table.
    #
    #    $self->{LicenseIncomeList}->createSales();

    # Now update our state.
    #
    $dbItem->file_status(Raptor::DB::Item::File::STATUS_CLOSED);
    $dbItem->date_finished( Common::Util::secondsToDateTime( time() ) );
    $dbItem->save();

    return $self->_init( _dbItem => $dbItem );
}

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

    # To re-open a file, we'll want to delete all the associated sales and set the status
    # of the file back to OPEN.
    #
    my $fileID = $self->FileID();
    assert( $fileID, "ERROR - cannot finish a file that has no file_id" );

    my $dbItem = Raptor::DB::Item::File->Lookup( file_id => $fileID );
    assert( $dbItem, "ERROR - invalid file_id $fileID" );

    assert( 0 == $self->{period_id}, "ERROR - cannot finish a file in a closed period" );
    assert( Raptor::DB::Item::File::STATUS_CLOSED == $dbItem->file_status,
        "ERROR - cannot re-open a file that is not CLOSED: file_id $fileID, status = " . $dbItem->file_status );

    # So, in this step, we'll create entries in the Sale table.
    #
    #    $self->{LicenseIncomeList}->deleteSales();

    # Now update our state.
    #
    $dbItem->file_status(Raptor::DB::Item::File::STATUS_OPEN);
    $dbItem->date_finished('0000-00-00 00:00:00');
    $dbItem->save();

    return $self->_init( _dbItem => $dbItem );
}

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

    # Can't delete a file unless it is in an open period.
    # I don't think you can delete a file that is CLOSED either.
    #
    my $fileID = $self->FileID();
    assert( $fileID, "ERROR - cannot finish a file that has no file_id" );

    my $dbItem = Raptor::DB::Item::File->Lookup( file_id => $fileID );
    assert( $dbItem, "ERROR - invalid file_id $fileID" );

    assert( 0 == $self->{period_id}, "ERROR - cannot delete a file in a closed period" );
    assert( Raptor::DB::Item::File::STATUS_OPEN == $dbItem->file_status,
        "ERROR - cannot delete -open a file that is not OPEN: file_id $fileID, status = " . $dbItem->file_status );

    # We want to delete all the sales and license_income entries.
    #
    $self->{LicenseIncomeList}->deleteAll();

    $dbItem->delete();
}

1;
