var ce = require('cloneextend');
var mongoose = require('mongoose');
var ObjectId = mongoose.Types.ObjectId;
var fs = require('fs');
var should = require('should');
var assert = require('assert');
var path = require('path');
var inspect = require('eyespect').inspector();

var scraperProcessData = require('../scraperProcessData');

// Utility
var getCostDelivery = require('../lib/parse/getCostDelivery');
var getUse = require('../lib/parse/getUse');
var getCostOther = require('../lib/parse/otherCosts/getCostOther');


// Supply
var getSupplyText = require('../lib/parse/getSupplyText');
var getCostSupply = require('../lib/parse/getCostSupply');
var getSupplyData = require('../lib/parse/getSupplyData');
var isCompSupply = require('../lib/parse/isCompSupply');
var getCompSupplier = require('../lib/parse/getCompSupplier');
var getCostOtherSupply = require('../lib/parse/comp/getCostOther');

// Models
var Bill = require('docparse-bill');
var Supplier = require('docparse-supplier');
var Invoice = require('docparse-invoice');
var createSupplier = require('docparse-create-supplier');
var getUtilityData = require('../lib/parse/getUtilityData');
describe('Parse Bill with standard offer supply data', function() {
  this.slow(200);
  var data, pagesText, testData;
  // desired defaults
  var supplyText = 'Supply Services\nTo enroll with a supplier or change to\nanother supplier you will need the             SUPPLIER   National Grid\nfollowing information about your account:\nLoadzone WCMA\nAcct No: 59011-88015       Cycle: 18 LOWE                 Basic Service Fixed                            0.07314 x 659 kWh                                          48.20\n                                                                                                             Total Supply Services                                $ 48.20';
  var costSupply = '0';
  var costDelivery = '0';
  var costOtherTotal = '1667.38';
  var costOtherNumCosts = 1;
  var toPaySupply = '';
  var costOtherSupplyTotal = '0';
  var costOtherSupplyNumCosts = 0;
  var useQuantity = '0';
  var useUnits = 'kwh';
  before(function (done) {
    mongoose.connect('mongodb://localhost/test');
    Supplier.remove({}, function (err) {
      Bill.remove({}, function (err) {
        should.not.exist(err);
        Invoice.remove({}, function (err) {
          should.not.exist(err);
          var filePath = path.join(__dirname, 'data', 'finalService1.json');
          assert.ok(fs.existsSync(filePath), 'test final service NGE json file not found at path: ' + filePath);
          var text = fs.readFileSync(filePath, 'utf8');
          should.exist(text ,'nge text not read from file at path: ' + filePath);
          data = JSON.parse(text);
          pagesText = data.textPages.join(' ').replace(/,/g, '');
          testData = {
            text: pagesText

          };
          var supplierData = {
            supplierCode: 'NGE',
            supplierName: 'NGrid Electric',
            remove: true
          };
          createSupplier(supplierData, function (err, reply) {
            should.not.exist(err);
            should.exist(reply);
            data.supplierID = reply._id.toString();
            data.loginID = new ObjectId();
            data.customerID = new ObjectId();
            data.supplierCode = 'NGE';
            done();
          });
        });
      });
    });
  });

  after(function (done) { mongoose.disconnect(done); });

  it('should get cost delivery correctly', function (done) {
    getCostDelivery(pagesText, function (err, reply) {
      should.not.exist(err, 'error getting cost: ' + err);
      should.exist(reply);
      costDelivery.should.eql(reply);
      done();
    });
  });

  it('should get use correctly', function (done) {
    getUse(pagesText, function (err, reply) {
      should.not.exist(err, 'error getting cost: ' + err);
      should.exist(reply);
      inspect(reply,'use');
      useQuantity.should.eql(reply.quantity);
      useUnits.should.eql(reply.units);
      done();
    });
  });

  it('should get costOther correctly', function (done) {
    getCostOther(pagesText, function (err, reply) {
      should.not.exist(err, 'error getting cost: ' + err);
      should.exist(reply);
      // inspect(reply, 'costOther reply');
      costOtherTotal.should.eql(reply.total);
      costOtherNumCosts.should.eql(reply.costs.length);
      done();
    });
  });

  it('should get utility data correctly', function (done) {
    getUtilityData(testData, function (err, reply) {
      should.not.exist(err, 'error getting utility data: ' + err);
      should.exist(reply);
      // inspect(reply, 'utility data reply');
      costDelivery.should.eql(reply.costDelivery);
      done();
    });
  });

  it('should get supply text correctly', function () {
    var text = getSupplyText(testData.text);
    // inspect(text);
    supplyText.should.eql(text);
  });

  it('should get cost supply correctly', function (done) {
    getCostSupply(supplyText, function (err, reply) {
      should.not.exist(err, 'error getting cost supply: ' + err);
      should.exist(reply);
      costSupply.should.eql(reply);
      done();
    });
  });

  it('comp supply should be true', function () {
    var isComp = isCompSupply(supplyText);
    assert.ok(!isComp, 'competitive supply should be false');
  });

  it('should comp supply cost other correctly', function (done) {
    var data = {
      costSupply: costSupply,
      text: supplyText
    };
    getCostOtherSupply(data, function (err, reply) {
      should.not.exist(err);
      should.exist(reply);
      costOtherSupplyTotal.should.eql(reply.costOther.total);
      toPaySupply.should.eql(reply.costTotal);
      done();
    });
  });

  it('should get supply data correctly', function(done) {
    var getData = require('../lib/parse/getData');
    getData(testData, function (err, reply) {
      if (err) {
        inspect(err, 'error getting data');
      }
      should.not.exist(err, 'error parsing data: ' + err);
      should.exist(reply, 'no reply returned from parsing scraper data');
      reply.should.have.property('costOther');
      costOtherTotal.should.eql(reply.costOther.total);
      done();
    });
  });

  it('should get supply data correctly', function(done) {
    scraperProcessData(data, function (err, reply) {
      if (err) {
        inspect(err, 'error processing scraper data');
      }
      should.not.exist(err, 'error parsing data: ' + err);
      should.exist(reply, 'no reply returned from parsing scraper data');
      var bill = reply.toObject();
      var invoiceIDs = bill.invoices;
      invoiceIDs.length.should.eql(1);
      var stdInvoiceID = invoiceIDs[0];
      Invoice.findById(stdInvoiceID, function (err, invoiceReply) {
        should.not.exist(err);
        should.exist(invoiceReply);
        var stdInvoice = invoiceReply.toObject();
        stdInvoice.data_type.should.eql('pdf');
        done();
      });
    });
  });

  it('should get handle duplicate bills correctl', function(done) {
    scraperProcessData(data, function (err, reply) {
      if (err) {
        inspect(err, 'error processing scraper data');
        return;
      }
      should.not.exist(err, 'error parsing data: ' + err);
      should.exist(reply);
      done();
    });
  });
});
