package Business::OnlinePayment::PaymentsGateway;

use strict;
use Carp;
use Business::OnlinePayment
use Net::SSLeay qw(sslcat);
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $DEBUG);

require Exporter;

@ISA - qw( Exporter AutoLoader Business::OnlinePayment);
@EXPORT = qw();
@EXPORT_OK = qw();
$VERSION = '0.01';

$DEBUG = 0;

sub set_defaults {
  my $self = shift;
  $self->server('');
  $self->port( 5050 + 1000 * $self->test_transaction() );
  #$self->build_subs();
}

sub map_fields {
  my $self = shift;
  my %content = $self->content();

  #ACTION MAP
  my %actions = (
    'normal authorization' => 0,
    'authorization only'   => 1,
    'post authorization'   => 2,
    'credit'               => 3,
  );

  my %types = (
    'visa'             => 10,
    'mastercard'       => 10,
    'american express' => 10,
    'discover'         => 10,
    'cc'               => 10,
    'check'            => 20,
  );

  #pg_type/action = action + type  

  $self->transaction_type( $actions{ lc($content{'action'}) } 
                           + $types{ lc($content{'type'  }) }    );

  #$self->content(%content);
}

sub revmap_fields {
    my($self, %map) = @_;
    my %content = $self->content();
    foreach(keys %map) {
        $content{$_} = ref($map{$_})
                         ? ${ $map{$_} }
                         : $content{$map{$_}};
    }
    $self->content(%content);
}

sub submit {
  my $self = shift;
  $self->map_fields();

  my %content = $self->content();

  $self->revmap_fields( 
    'pg_merchant_id'                   => 'login',
    'pg_password'                      => 'password',
    'pg_transaction_type'              => \($self->transaction_type()),
    #'pg_merchant_data_1'
    #...
    #'pg_merchant_data_9'
    'pg_total_amount'                  => 'amount',
    #'pg_sales_tax_amount'
    'pg_consumer_id'                   => 'customer_id',
    'ecom_consumerorderid'             => 'invoice_number', #???
    #'ecom_walletid'                    =>
    'pg_billto_postal_name_company'    => 'company', #????
    'ecom_billto_postal_name_first'    => 'first_name', #????
    'ecom_billto_postal_name_last'     => 'last_name', # ????
    'ecom_billto_postal_street_line1'  => 'address',
    #'ecom_billto_postal_street_line2'
    'ecom_billto_postal_city'          => 'city',
    'ecom_billto_postal_stateprov'     => 'state',
    'ecom_billto_postal_postalcode'    => 'zip',
    'ecom_billto_postal_countrycode'   => 'country',
    'ecom_billto_telecom_phone_number' => 'phone',
    'ecom_billto_online_email'         => 'email',
    #'pg_billto_ssn'
    #'pg_billto_dl_number'
    #'pg_billto_dl_state'
    'ecom_payment_check_trn'           => 'routing_code',
    'ecom_payment_check_account'       => 'account_number',
    'ecom_payment_check_account_type'  => \'C', #checking
    #'ecom_payment_check_checkno'       =>
  );

  # name (first_name & last_name ) ?
  # fax

  # card_number exp_date

  #account_number routing_code bank_name

  my @fields = qw( pg_merchant_id pg_password pg_transaction_type ),
               ( map { "pg_merchant_$_" } (1..9) ),
               qw( pg_total_amount pg_sales_tax_amount pg_consumer_id
                   ecom_consumerorderid ecom_walletid
                   pg_billto_postal_name_company
                   ecom_billto_postal_name_first ecom_billto_postal_name_last
                   ecom_billto_postal_street_line1
                   ecom_billto_postal_street_line2
                   ecom_billto_postal_city ecom_billto_postal_stateprov
                   ecom_billto_postal_postalcode ecom_billto_postal_countrycode
                   ecom_billto_telecom_phone_number ecom_billto_online_email
                   pg_billto_ssn pg_billto_dl_number pg_billto_dl_state
               );

  if ( $content{'type'} =~ /^check$/i ) {
    push @fields, qw( ecom_payment_check_trn
                      ecom_payment_check_account
                      ecom_payment_check_account_type );
  } else {
    croak $content{$type}. ' not (yet) supported';
  }

  my $request = join("\n", map { "$_=$content{$_}" } @fields ). "\n";

  my $reply = sslcat( $self->server(), $self->port(), $request );

  my %response = map { /^(\w+)=(.*)$/
                         or warn "can't parse response line: $_";
                       ($1, $2);
                     } split(/\n/, $reply);

  if ( $response{'pg_response_type'} eq 'A' ) {
    $self->is_success(1);
    $self->response_code($response{'pg_response_code'});
    $self->authorization($response{'pg_authorization_code'});
  } else {
    $self->is_success(0);
    $self->response_code($response{'pg_response_code'});
    $self->error_message($response{'pg_response_description'});
  }
}

1;

#pod goes here

