'use strict';

var _    = require('underscore');
var path = require('path');
var URL  = require('url');

var name = "pay-worldpay-checkout";

module.exports = function(options) {

  var seneca = this;

  var endpoints = {
    pay: '/pay/worldpay-checkout/pay',
    completeCallback: '/pay/worldpay-checkout/callback-complete',
    cancelCallback: '/pay/worldpay-checkout/callback-cancel'
  }

  seneca.add({role:name, cmd:'init-gateway'}, function (args, done) {
    var options = args.options;

    done(null);
  })

  var hostUrl;
  var successUrl, failUrl;

  seneca.add({role:name, cmd:'init-routes'}, function (args, done) {
    var routes = args.routes;

    if(args.redirect) {
      //this bit should probably just be removed.
      hostUrl = args.redirect.hostUrl;
      successUrl = args.redirect.success;
      failUrl = args.redirect.fail;
    } else {
      hostUrl    = options.redirect.hostUrl;
      successUrl = options.redirect.success;
      failUrl    = options.redirect.fail;
    }

    routes[endpoints.pay] = { POST:payHandler };
    routes[endpoints.completeCallback] = { GET:completeCallbackHandler, POST:completeCallbackHandler };
    routes[endpoints.cancelCallback] = { GET:cancelCallbackHandler, POST:cancelCallbackHandler };

    done(null, routes);
  })

  function urlappend(url, name, value) {
    var urlobj = URL.parse(url, true);
    if (typeof value !== 'undefined' && value !== null) {
      urlobj.query[name] = value;
    }
    return URL.format(urlobj);
  }

  function payHandler(req, res, next) {

    var input = req.body;
    var transactionData = {
      refno:input.refno,
      status:'created',
      customer: {
        name: input.name,
        company: input.company,
        email: input.email
      },
      description: input.description,
      priceTag: input.priceTag,
      amount: input.amount,
      currencyCode: input.currencyCode,
      plan: input.plan
    };

    seneca.act({role:'transaction', cmd:'create', data:transactionData}, function(err, out) {
      if (err) {
        res.redirect(urlappend(failUrl, 'refno', input.refno));
        return
      }

      var transaction = out.transaction;

      var completeCallbackUrl = urlappend(urljoin(host, endpoints.completeCallback), 'refno', transaction.refno);
      var cancelCallbackUrl = urlappend(urljoin(host, endpoints.cancelCallback), 'refno', transaction.refno);

      // Do worldpay XML redirect to get redirect URL

      seneca.log.debug('beginPayment: init transaction', data.payment_url);

      // transaction.expressCheckout = data;
      transaction.status = 'started';

      seneca.act({role:'transaction', cmd:'update', id:transaction.id, data:transaction}, function(err) {
        seneca.log.debug('beginPayment: redirecting to', data.payment_url);

        res.redirect(data.payment_url);
      });
    });

  }

  function completeCallbackHandler(req, res, next) {

    // refno - internal transaction reference number
    var refno = req.query['refno'] || req.body['refno'];

    // need a stripe token?
    // var stripeToken = req.query['stripeToken'] || req.body['stripeToken'];
    // if (typeof stripeToken ==='undefined' || stripeToken===null || stripeToken.length===0) {
    //     seneca.log.error('complete', 'transaction', 'error', new Error('No token'), {refno:refno})
    //     res.redirect(urlappend(failUrl, 'refno', refno));
    //     return
    // }

    // lookup transaction by refno
    seneca.act({role:'transaction', cmd:'find', q:{'refno':refno}}, function(err, out) {
      if (err) {
        seneca.log.error('find', 'transaction', 'error', err, {refno:refno})
        res.redirect(urlappend(failUrl, 'refno', refno));
        return;
      }

      var transaction = out.transaction;
      transaction.status = 'completed';

      seneca.act({role:'transaction', cmd:'update', id:transaction.id, data:transaction}, function(err) {
        res.redirect(urlappend(successUrl, 'refno', transaction.refno));
      });

    });

  }

  function cancelCallbackHandler(req, res, next) {
    var refno = req.query['refno'];

    seneca.act({role:'transaction', cmd:'find', q:{'refno':refno}}, function(err, out) {
      if (err) {
        seneca.log.error('find', 'transaction', 'error', err, {token:token})
        res.redirect(urlappend(failUrl, 'refno', refno));
        return;
      }

      var transaction = out.transaction;
      transaction.status = 'cancelled';

      seneca.act({role:'transaction', cmd:'update', id:transaction.id, data:transaction}, function(err) {
        res.redirect(urlappend(failUrl, 'refno', refno));
      });
    });
  }

  return {
    name: name
  };

};

@@ -993,24 +993,135 @@
 ail;%0A    %7D%0A%0A
+    seneca.log.info('success url', hostUrl + successUrl);%0A    seneca.log.info('fail url', hostUrl + failUrl);%0A%0A
     routes%5Be
@@ -1137,16 +1137,32 @@
 pay%5D = %7B
+ GET:payHandler,
  POST:pa
@@ -2332,32 +2332,35 @@
 end(urljoin(host
+Url
 , endpoints.comp
@@ -2455,16 +2455,19 @@
 oin(host
+Url
 , endpoi

Fix hostUrl variable