#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package RPS::MapFace::MapFaceTempMapping;

use strict;
use warnings;
use Data::Dumper;

use lib '/app/tools/data_classes/lib';
use Client::Service;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::MapFaceTempMapping;
use RPS::DB::Item::MapFaceTempMappingCriteria;
use RPS::DB::Item::MapFaceTempMappingHistory;
use RPS::DB::Item::SaleImportError;
use RPS::DB::Item::User;
use RPS::MapFace::MapFaceTempMappingHistoryList;
use RPS::Import::Importer;

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::RSApp;
use Common::Util;
use Common::DB::Item::MapFaceFile;
use Common::DB::Item::MapFaceService;
use Common::DB::Item::Client;
use Common::FormObject;
use base 'Common::FormObject';

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

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

    my %properties;

    if ( $args{_dbItem} ) {
        $self->_propertiesFromDBItem( \%properties, $args{_dbItem} );
    } else {
        my $fileID       = $args{fileID};
        my $mappingGroup = $args{mappingGroup};
        assert($fileID);
        assert($mappingGroup);

        my $mapFaceTempMapping = RPS::DB::Item::MapFaceTempMapping->GetByFileAndGroup( $fileID, $mappingGroup );
        while ( $mapFaceTempMapping->hasNext() ) {
            my $tempMapping = $mapFaceTempMapping->next();
            $self->_propertiesFromDBItem( \%properties, $tempMapping );
        }
    }

    $self->_initProperties( \%properties );

    return $self;
}

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

    $hrProperties->{mapface_temp_mapping_id} = $dbItem->mapface_temp_mapping_id;
    $hrProperties->{file_id}                 = $dbItem->file_id;
    $hrProperties->{group_num}               = $dbItem->group_num;
    $hrProperties->{service_id}              = $dbItem->service_id;
    $hrProperties->{product_type}            = $dbItem->product_type;
    $hrProperties->{format_type}             = $dbItem->format_type;
    $hrProperties->{media_type}              = $dbItem->media_type;
    $hrProperties->{country_code}            = $dbItem->country_code;
    $hrProperties->{resolving_user_id}       = $dbItem->resolving_user_id;
    $hrProperties->{approving_user_id}       = $dbItem->approving_user_id;
    $hrProperties->{status}                  = $dbItem->status;
}

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

    $self->{MapFaceTempMappingID} = Common::FormObject::Scalar->new( value => $props->{mapface_temp_mapping_id}, readOnly => 1 );
    $self->{FileID}               = Common::FormObject::Scalar->new( value => $props->{file_id} );
    $self->{GroupNum}             = Common::FormObject::Scalar->new( value => $props->{group_num} );
    $self->{ServiceID}            = Common::FormObject::Scalar->new( value => $props->{service_id} );
    $self->{ProductType}          = Common::FormObject::Scalar->new( value => $props->{product_type} );
    $self->{FormatType}           = Common::FormObject::Scalar->new( value => $props->{format_type} );
    $self->{MediaType}            = Common::FormObject::Scalar->new( value => $props->{media_type} );
    $self->{CountryCode} = Common::FormObject::Scalar::String->new( value => $props->{country_code} );
    $self->{ResolvingUserID} = Common::FormObject::Scalar->new( value => $props->{resolving_user_id} );
    $self->{ApprovingUserID} = Common::FormObject::Scalar->new( value => $props->{approving_user_id} );
    $self->{Status}          = Common::FormObject::Scalar->new( value => $props->{status} );

    if ( $props->{resolving_user_id} ) {
        my $resolvingUser = RPS::DB::Item::User->Lookup( user_id => $props->{resolving_user_id} );
        $self->{ResolvingUserName} = $resolvingUser->first_name . " " . $resolvingUser->last_name;
    }

    if ( $props->{approving_user_id} ) {
        my $approvingUser = RPS::DB::Item::User->Lookup( user_id => $props->{approving_user_id} );
        $self->{ApprovingUserName} = $approvingUser->first_name . " " . $approvingUser->last_name;
    }

    if ( $props->{mapface_temp_mapping_id} ) {
        $self->{MapFaceTempMappingHistoryList} =
          RPS::MapFace::MapFaceTempMappingHistoryList->new( mapFaceTempMappingID => $props->{mapface_temp_mapping_id} );
    }

    my $serviceName;

    if ( $props->{service_id} ) {
        my $service = RPS::DB::Item::Service->Lookup( service_id => $props->{service_id} );
        if ( !$service ) {
            $service = Common::DB::Item::MapFaceService->Lookup( service_id => $props->{service_id} );
        }
        if ($service) {
            $serviceName = $service->service_name;
        }
    }

    $self->{ServiceName} = Common::FormObject::Scalar::String->new( value => $serviceName );
}

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

    my $valid = 1;

    # Prevent mapping to soundexchange
    if ( $self->ServiceID() == Client::Service::DSP_SOUNDEXCHANGE ) {
        $valid = 0;
        $self->{ServiceID}->setError(Common::FormObject::kErrFieldInvalid);
    }

    return $valid;
}

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

    my $fileID   = $self->FileID();
    my $clientID = Common::RSApp::GetClientID();

    my $dbObj;
    if ( defined $self->MapFaceTempMappingID() ) {
        $dbObj = RPS::DB::Item::MapFaceTempMapping->Lookup( mapface_temp_mapping_id => $self->MapFaceTempMappingID() );
    } else {
        $dbObj = RPS::DB::Item::MapFaceTempMapping->Create();
    }

    # If applicable, we'll need to create the new service now so that we can get the new service id to store.
    if ( !$self->ServiceID() && $self->ServiceName() ) {

        # Let's make sure that we really don't have this service already.
        # If you're quick enough, you can fool the auto-complete into thinking it's
        # a new name when it's not.
        my $serviceID = $self->RPS::Import::Importer::getServiceID( lc( $self->ServiceName() ) );

        # Also need to check mapface_service table in common
        if ( !$serviceID ) {
            my $mapfaceService = Common::DB::Item::MapFaceService->Lookup( service_name => $self->ServiceName() );
            if ( defined $mapfaceService && lc( $mapfaceService->service_name ) eq lc( $self->ServiceName() ) ) {
                $serviceID = $mapfaceService->service_id;
            }
        }

        if ($serviceID) {
            $self->ServiceID($serviceID);
        } else {
            my $serviceObj = Common::DB::Item::MapFaceService->Create( service_name => $self->ServiceName() );
            $serviceObj->service_name_clean( Common::Util::clean_name( $self->ServiceName() ) );
            $serviceObj->save();
            $self->ServiceID( $serviceObj->service_id );
        }
    }

    if ( $self->ServiceID() ) {

        # Also, this may be a regular service that we have in Client::Service,
        # but not in the client's database yet.  In that case,
        # let's add it to the client's database now.
        my $mapfaceService = Common::DB::Item::MapFaceService->Lookup( service_id => $self->ServiceID() );

        if ( !$mapfaceService ) {
            Client::Service::AddService(
                client_id  => $clientID,
                service_id => $self->ServiceID()
            );
        }
    }

    my $userID = Common::RSApp::GetActiveUserID();

    # set fields here
    #
    $dbObj->file_id($fileID);
    $dbObj->group_num( $self->GroupNum() );
    $dbObj->service_id( $self->ServiceID() );
    $dbObj->product_type( $self->ProductType() );
    $dbObj->format_type( $self->FormatType() );
    $dbObj->media_type( $self->MediaType() );
    $dbObj->country_code( $self->CountryCode() );
    $dbObj->status(RPS::DB::Item::MapFaceTempMapping::STATUS_MAPPED);
    $dbObj->resolving_user_id($userID);

    # save db item
    #
    $dbObj->save();

    # reload object
    #
    $self->_init( _dbItem => $dbObj );

    # Now we need to update the remaining_errors field in the mapface_file table in RSCOMMON.
    my $remainingCount = RPS::DB::Item::MapFaceTempMapping->GetRemainingErrorCountByFileID($fileID);
    my $mapFaceFiles = Common::DB::Item::MapFaceFile->GetByClientAndFileID( $clientID, $fileID );
    while ( $mapFaceFiles->hasNext() ) {
        my $mapFaceFile = $mapFaceFiles->next();
        $mapFaceFile->remaining_errors($remainingCount);
        $mapFaceFile->resolving_user_id($userID);

        if ( $remainingCount == 0 ) {
            $mapFaceFile->status(Common::DB::Item::MapFaceFile::STATUS_REVIEW);
        }

        $mapFaceFile->save();
    }

    # And add the event to this history.
    my $newHistoryAction = RPS::DB::Item::MapFaceTempMappingHistory->Create(
        mapface_temp_mapping_id => $self->MapFaceTempMappingID(),
        user_id                 => $userID,
        action                  => RPS::DB::Item::MapFaceTempMappingHistory::kActionMapped,
    );

    $newHistoryAction->save();
}

sub delete {
    my $self = shift;

    # First let's get rid of the mapping criteria.
    RPS::DB::Item::MapFaceTempMappingCriteria->DeleteByMappingID( $self->MapFaceTempMappingID );

    # Next the history
    RPS::DB::Item::MapFaceTempMappingHistory->DeleteByMappingID( $self->MapFaceTempMappingID );

    # And finally delete the mapping itself.
    my $myDBObj = RPS::DB::Item::MapFaceTempMapping->Lookup( mapface_temp_mapping_id => $self->MapFaceTempMappingID() );
    $myDBObj->delete();

    return 1;
}

1;
