/* globals by, protractor, browser */
'use strict';

var helper = require('./css-selector-builder'),
  utils = require('./utils');
var Logger = require('logb').getLogger(module.filename);
var EC = protractor.ExpectedConditions;

function User(opts) {
  opts = opts || {};
  this.browser = opts.browser || browser;
  this.currentProductName = null;
  this.username = 'wisse@wonderflow.co';
  this.password = 'wisse2015';
}
User.prototype.waitUntilReady = function(el) {
  return browser.wait(function() {
    return el.isPresent();
  }, 10000).then(function() {
    browser.wait(function() {
      return el.isDisplayed();
    }, 10000);
  });
};
User.prototype.convertHex = function(hex, opacity) {
  var result,
    r,
    g,
    b;
  opacity = opacity || 1;
  hex = hex.replace('#', '');
  r = parseInt(hex.substring(0, 2), 16);
  g = parseInt(hex.substring(2, 4), 16);
  b = parseInt(hex.substring(4, 6), 16);

  result = 'rgba(' + r + ', ' + g + ', ' + b + ', ' + opacity + ')';
  return result;
};

User.prototype.goTo = function(path) {
  console.log('Going to', utils.getEndPoint() + '' + path)
  return this.browser.get(utils.getEndPoint() + '/#' + path);
};

User.prototype.login = function() {
  return utils.login(this.username, this.password, this.browser);
};
User.prototype.pause = User.prototype.wait = function(secs) {
  return this.browser.sleep((secs || 1) * 1000);
};
User.prototype.takeScreenshot = function(filename) {
  var deferred = protractor.promise.defer();
  this.browser.takeScreenshot().then(function(data) {
    // browser.getCapabilities().then(function(capabilities) {
    browser.getCapabilities().then(function() {
      var currentSpec;

      currentSpec = jasmine.getEnv().currentSpec;
      // var browserName = capabilities.caps_.browserName;

      filename = filename || new Date().getTime();
      filename = filename + '.png';
      filename = require('path').resolve(__dirname, '../screenshots', filename);

      console.log('filename', filename);

      var stream = require('fs').createWriteStream(filename);

      stream.write(new Buffer(data, 'base64'));
      stream.end();
      console.log('Created image ' + filename);
      deferred.fulfill();


    });
  });
  return deferred.promise;
};
User.prototype.clickByCssSelector = function(cssSelector) {
  var el;
  var self = this;
  el = this.browser.element(by.css(cssSelector));
  return this.waitUntilReady(el)
    .then(function() {
      return self.browser.executeScript('window.scrollTo(0,arguments[0].scrollHeight+' + 100 + ');', el.getWebElement());
    })
    .then(function() {
      // return this.browser.executeScript('arguments[0].scrollIntoView(true)', el.getWebElement()).then(function(){
      self.takeScreenshot('not clickable');
      return el.click();
    });
};


User.prototype.sendKeysByCssSelector = function(cssSelector, text) {
  var el;
  var self = this;
  el = this.browser.element(by.css(cssSelector));
  return this.waitUntilReady(el).then(function() {
    return self.browser.executeScript('window.scrollTo(0,arguments[0].scrollHeight+' + 100 + ');', el.getWebElement());
  }).then(function() {
    // return this.browser.executeScript('arguments[0].scrollIntoView(true)', el.getWebElement()).then(function(){
    self.takeScreenshot('unable to send keys');
    return el.sendKeys(text);
  });
};


User.prototype.clickByXpathSelector = function(cssSelector) {
  var el;
  var self = this;
  el = this.browser.element(by.xpath(cssSelector));
  return this.waitUntilReady(el).then(function() {
    return self.browser.executeScript('window.scrollTo(0,arguments[0].scrollHeight+' + 100 + ');', el.getWebElement());
  }).then(function() {
    self.takeScreenshot('not clickable');
    return el.click().then(null, function(err) {
      var now = new Date().getTime();
      console.trace('Exception ' + now, err);
      self.takeScreenshot('not-clickable-' + now);
      return browser.waitForAngular();
    });
  });
};
User.prototype.goToInsightsListByProductId = function(productId) {
  return this.goTo('/insights/' + productId);
};
User.prototype.countInsightByInsightText = function(insightText) {
  return this.browser.element.all(by.css('.insight-text-input')).filter(function(el) {
    return el.getAttribute('value').then(function(text) {
      // console.log('...', text, insightText)
      return text === insightText;
    });
  }).then(function(els) {
    return els.length;
  });
};

User.prototype._scrollToElement = function(el) {
  return this.browser.executeScript('arguments[0].scrollIntoView(true)', el.getWebElement());
};

User.prototype.scrollToElement = User.prototype.scrollTo = function(element, offset) {

  var self = this;
  offset = offset || 0;

  return element.getLocation()
    .then(function(location) {
      var y = location.y + offset;
      Logger.info('Scrolling to', y);
      self.browser.executeScript('window.scrollTo(0, ' + y + ')');
    });
};
User.prototype.scrollToTop = function() {

  var self = this;
  var top = 0;

  // return element.getLocation()

  //   .then(function(location) {
  self.browser.executeScript('window.scrollTo(0, ' + 0 + ')');
  // });
};

User.prototype.openProductPanelByProductName = function(productName) {
  Logger.info('Opening product pagel by product name...');
  this.currentProductName = productName;
  return this.browser.element(by.xpath(helper.getPanelTitleSelectorByProductName(this.currentProductName))).click();
};
User.prototype.appendToProductName = function(str) {
  this.browser.element(by.xpath(helper.getInputProductNameSelectorByProductName(this.currentProductName))).sendKeys(str);
};
// country
User.prototype.setCountryToAdd = function(str) {
  this.browser.element(by.xpath(helper.getCountryInputByProductName(this.currentProductName))).sendKeys(str);
};
// price range
User.prototype.appendToPriceRangeMin = function(str) {
  this.browser.element(by.xpath(helper.getPriceRangeMinSelector(this.currentProductName))).sendKeys(str);
};
User.prototype.appendToPriceRangeMax = function(str) {
  this.browser.element(by.xpath(helper.getPriceRangeMaxSelector(this.currentProductName))).sendKeys(str);
};
User.prototype.clickToUpdatePriceRange = function() {
  return this.browser.element(by.xpath(helper.getButtonToUpdatePriceRangeSelector(this.currentProductName))).click();
};



// number of reviews
User.prototype.clickToUpdateNumberOfReviews = function() {
  return this.browser.element(by.xpath(helper.getButtonToUpdateReviewsSelector(this.currentProductName))).click();
};
User.prototype.readTotalNumberOfReviews = function() {
  return this.browser.element(by.xpath(helper.getTotalNumberOfReviewsSelector(this.currentProductName))).getText();
};
User.prototype.readNumberOfSampledReviews = function() {
  return this.browser.element(by.xpath(helper.getNumberOfSampledReviewsSelector(this.currentProductName))).getText();
};
User.prototype.readNumberOfAnalyzedReviews = function() {
  return this.browser.element(by.xpath(helper.getNumberOfAnalyzedReviewsSelector(this.currentProductName))).getText();
};
User.prototype.clickToPublishAnalyzedAndUnpublishedReviews = function() {
  this.browser.element(by.xpath(helper.getButtonToPublishAnalyzedAndUnpublishedReviewsSelector(this.currentProductName))).click();
};
// price range
User.prototype.readPriceRangeMax = function() {
  return this.browser.element(by.xpath(helper.getPriceRangeMaxSelector(this.currentProductName))).getAttribute('value');
};
User.prototype.readPriceRangeMin = function() {
  return this.browser.element(by.xpath(helper.getPriceRangeMinSelector(this.currentProductName))).getAttribute('value');
};


// companyID
User.prototype.readCompanyIDs = function() {
  return this.browser.element.all(by.xpath(helper.getCompanyIDSelector(this.currentProductName))).map(function(el) {
    return el.getText();
  });
};
User.prototype.setCompanyIdToAdd = function(value) {
  return this.browser.element(by.xpath(helper.getCompanyIdInputSelector(this.currentProductName))).sendKeys(value);
};
User.prototype.clickToAddCompanyId = function() {
  return this.browser.element.all(by.xpath(helper.getCompanyIDAddButton(this.currentProductName))).click();
};
// sku
User.prototype.readSkus = function() {
  return this.browser.element.all(by.xpath(helper.getSkusSelector(this.currentProductName))).map(function(el) {
    return el.getText();
  });
};
User.prototype.setSkuToAdd = function(value) {
  return this.browser.element(by.xpath(helper.getSkuInputSelector(this.currentProductName))).sendKeys(value);
};
User.prototype.clickToAddSku = function() {
  return this.browser.element.all(by.xpath(helper.getSkuAddButton(this.currentProductName))).click();
};
// review title
User.prototype.readReviewTitles = function() {
  return this.browser.element.all(by.xpath(helper.getReviewTitlesSelector(this.currentProductName))).map(function(el) {
    return el.getText();
  });
};
User.prototype.setReviewTitleToAdd = function(value) {
  return this.browser.element(by.xpath(helper.getReviewTitleInputSelector(this.currentProductName))).sendKeys(value);
};
User.prototype.clickToAddReviewTitle = function() {
  return this.browser.element.all(by.xpath(helper.getReviewTitleAddButton(this.currentProductName))).click();
};
// price and product category
User.prototype.readPriceCategory = function() {
  return this.browser.element(by.xpath(helper.getPriceCategorySelector(this.currentProductName))).$('option:checked').getText();
};
User.prototype.setPriceCategory = function(value) {
  return this.browser.element(by.xpath(helper.getPriceCategoryOptionSelector(this.currentProductName, value))).click();
};
User.prototype.readProductCategory = function() {
  return this.browser.element(by.xpath(helper.getProductCategorySelectValueSelector(this.currentProductName))).$('option:checked').getText();
};
User.prototype.setProductCategory = function(value) {
  return this.browser.element(by.xpath(helper.getProductCategoryOptionSelector(this.currentProductName, value))).click();
};
// assignment of language to analyst
User.prototype.readAssignmentsAnalystToLanguage = function() {
  return this.browser.element.all(by.xpath(helper.getAssignmentsAnalystToLanguageSelector(this.currentProductName))).map(function(el) {
    return el.getText();
  });
};
User.prototype.selectAnalystToAssign = function(value) {
  return this.browser.element(by.xpath(helper.getAnalystSelector(this.currentProductName, value))).click();
};
User.prototype.selectLanguageToAssign = function(value) {
  return this.browser.element(by.xpath(helper.getLanguageSelector(this.currentProductName, value))).click();
};
User.prototype.clickToAssignAnalyastToLanguage = function() {
  return this.browser.element(by.xpath(helper.getAssigningButtonSelector(this.currentProductName))).click();
};
User.prototype.selectDataSourceToAssign = function(value) {
  return this.browser.element(by.xpath(helper.getDataSourceSelector(this.currentProductName, value))).click();
};
// TODO: here

User.prototype.deAssignByAnalystAndLanguage = function(analystName, language) {
  return this.browser.element(by.xpath(helper.getAssignmentAnalystToLanguage(this.currentProductName, analystName, language))).click();
};
//
// assignment of sku to review title
User.prototype.readFirstAssignmentSkuToReviewTitle = function() {
  return this.browser.element.all(by.xpath(helper.getFirstAssignmentSkuToReviewTitleSelector(this.currentProductName))).get(0).$('option:checked').getText();
};
User.prototype.selectSkuToAssign = function(value) {
  return this.browser.element.all(by.xpath(helper.getSkuSelector(this.currentProductName, value))).get(0).click();
};
// channels
User.prototype.updateChannels = function() {
  return this.browser.element(by.xpath(helper.getUpdateChannelButtonSelector(this.currentProductName))).click();
};

User.prototype.readChannels = function() {
  //console.log('helper.getChannelsSelector(this.currentProductName)', helper.getChannelsSelector(this.currentProductName));
  return this.browser.element.all(by.xpath(helper.getChannelsSelector(this.currentProductName))).map(function(el) {
    return el.getText();
  });
};

User.prototype.readMinDate = function() {
  return this.browser.element(by.xpath(helper.getMinDateSelector(this.currentProductName))).getText();
};
User.prototype.readMaxDate = function() {
  return this.browser.element(by.xpath(helper.getMaxDateSelector(this.currentProductName))).getText();
};
User.prototype.clickToUpdateMinAndMaxDate = function() {
  return this.browser.element(by.xpath(helper.getUpdateMinAndMaxDateButtonSelector(this.currentProductName))).click();
};

User.prototype.readLanguages = function() {
  console.log(helper.getLanguagesSelector(this.currentProductName));
  return this.browser.element.all(by.xpath(helper.getLanguagesSelector(this.currentProductName))).map(function(el) {
    return el.getText();
  });
};
User.prototype.clickToUpdateLanguages = function() {
  return this.browser.element(by.xpath(helper.getUpdateLanguagesButtonSelector(this.currentProductName))).click();
};
User.prototype.readAvgRating = function() {
  return this.browser.element(by.xpath(helper.getAvgRatingSelector(this.currentProductName))).getText();
};
User.prototype.clickToUpdateRating = function() {
  return this.browser.element(by.xpath(helper.getUpdateAvgRatingButtonSelector(this.currentProductName))).click();
};
User.prototype.clickToUpdateWonderboardVisibility = function() {
  return this.browser.element(by.xpath(helper.getWonderboardVisibilityCheckboxSelector(this.currentProductName))).click();
};
User.prototype.readWonderboardVisibility = function() {
  return this.browser.element(by.xpath(helper.getWonderboardVisibilityCheckboxSelector(this.currentProductName))).isSelected();
};
User.prototype.clickToUpdateAnnotationAppVisibility = function() {
  return this.browser.element(by.xpath(helper.getAnnotationAppVisibilityCheckboxSelector(this.currentProductName))).click();
};
User.prototype.readAnnotationAppVisibility = function() {
  return this.browser.element(by.xpath(helper.getAnnotationAppVisibilityCheckboxSelector(this.currentProductName))).isSelected();
};
User.prototype.clickOnEditInsights = function() {
  return this.clickByXpathSelector(helper.getEditInsightsTriggerSelector(this.currentProductName));
};

// linked-reviews
User.prototype.readInsightText = function() {
  return this.browser.element(by.xpath(helper.getInsightTextSelector())).getText();
};
User.prototype.readNumberOfLinkedReviews = function() {
  return this.browser.element(by.xpath(helper.getNumberOfLinkedReviewsSelector())).getText();
};
User.prototype.countNumberOfVisualizedLinkedReviews = function() {
  return this.browser.element.all(by.xpath(helper.getVisualizedLinkedReviewsSelector()))
    .filter(function(el) {
      return el.isPresent();
    })
    .filter(function(el) {
      return el.isDisplayed();
    }).count();
};
User.prototype.readTitleOfFirstLinkedReview = function() {
  return this.browser.element.all(by.xpath(helper.getTitleOfFirstLinkedReviewSelector())).get(0).getText();
};
User.prototype.clickToUnlinkLinkedReview = function() {
  var el;
  var self = this;
  el = this.browser.element(by.xpath(helper.getButtonToUnlinkFirstLinkedReviewSelector()));
  //   return self.scrollToElement(el,200)
  //     .then(function() {
  return self.takeScreenshot('no-click')
    // })
    .then(function() {
      return el.click();
    });
};
User.prototype.clickOnNextPage = function() {
  var el = this.browser.element(by.xpath('//*[contains(@class,"w-go-to-next-page")]'));
  this._scrollToElement(el);
  return el.click();
};
User.prototype.isNextPageButtonDisplayed = function() {
  var el = this.browser.element(by.xpath('//*[contains(@class,"w-go-to-next-page")]'));
  return this._scrollToElement(el).then(function() {
    return el.isDisplayed();
  });
};
// quality-check
User.prototype.readRawTextReviewItems = function() {
  return this.browser.element.all(by.xpath('//*[contains(@class,"w-quality-check-on-text-reviews-item")]')).map(function(el) {
    var index = el.getWebElement().findElement(by.className('w-index')).getText();
    var fieldName = el.getWebElement().findElement(by.className('w-field-name')).getText();
    var issueName = el.getWebElement().findElement(by.className('w-type')).getText();
    var numberOfReviews = el.getWebElement().findElement(by.className('w-number-of-reviews')).getText();
    return {
      index: index,
      fieldName: fieldName,
      type: issueName,
      numberOfReviews: numberOfReviews
    };
  });
};
User.prototype.readTextReviewItems = function() {
  return this.browser.element.all(by.xpath('//*[contains(@class,"w-quality-check-on-analyzed-reviews-item")]')).map(function(el) {
    var index = el.getWebElement().findElement(by.className('w-index')).getText();
    var fieldName = el.getWebElement().findElement(by.className('w-field-name')).getText();
    var issueName = el.getWebElement().findElement(by.className('w-type')).getText();
    var numberOfReviews = el.getWebElement().findElement(by.className('w-number-of-reviews')).getText();
    return {
      index: index,
      fieldName: fieldName,
      type: issueName,
      numberOfReviews: numberOfReviews
    };
  });
};



// product-filter-component-ui
User.prototype.clickToOpenProductFilterUiComponent = function() {
  this.browser.element(by.xpath('(//button[contains(@class,"w-open-product-filter-component-ui")])[1] ')).click();
};
User.prototype.clickOnProductInProductFilterUiComponentByProductName = function(productName) {
  var el;
  el = this.browser.element(by.xpath('(//div[contains(@class,"w-product-filter-component-ui")]//li[contains(@class,"w-product-human-id")  ]/a[contains(text(),"' + productName + '")])[1] '));
  browser.executeScript('arguments[0].scrollIntoView(false)', el.getWebElement());
  el.click();
};

User.prototype.addNewSkuToProduct = function(productIndex, skuValue) {

  var self = this;
  var inputElement;

  return self.browser.element.all(by.css('.w-product-sku-section .w-add-sku-input'))

  .then(function(elements) {
    inputElement = elements[productIndex];
    return self.scrollToElement(inputElement);
  })

  .then(function() {
    return inputElement.sendKeys(skuValue);
  })

  .then(function() {
    return element.all(by.css('.w-product-sku-section .w-add-sku-button'));
  })

  .then(function(buttons) {
    buttons[productIndex].click();
  });
};

User.prototype.editMinPriceRangeOfSku = function(productIndex, skuIndex, value) {

  var self = this;
  var skuSection;
  var inputElement;

  return self.browser.element.all(by.css('.w-product-sku-section'))

  .then(function(skuSections) {
    skuSection = skuSections[productIndex];
    return self.scrollToElement(skuSection);
  })

  .then(function() {
    return skuSection.all(by.css('.w-sku-min-price-input'));
  })

  .then(function(inputElements) {
    inputElement = inputElements[skuIndex];
    return inputElements[skuIndex].clear();
  })

  .then(function() {
    return inputElement.sendKeys(value);
  })

  .then(function() {
    return skuSection.element(by.css('.w-sku-max-price-input')).click();
  });
};

User.prototype.editMaxPriceRangeOfSku = function(productIndex, skuIndex, value) {

  var self = this;
  var skuSection;
  var inputElement;

  return self.browser.element.all(by.css('.w-product-sku-section'))

  .then(function(skuSections) {
    skuSection = skuSections[productIndex];
    return self.scrollToElement(skuSection);
  })

  .then(function() {
    return skuSection.all(by.css('.w-sku-max-price-input'));
  })

  .then(function(inputElements) {
    inputElement = inputElements[skuIndex];
    return inputElements[skuIndex].clear();
  })

  .then(function() {
    return inputElement.sendKeys(value);
  })

  .then(function() {
    return skuSection.element(by.css('.w-sku-min-price-input')).click();
  });
};

User.prototype.editPriceCategoryOfSku = function(productIndex, skuIndex, optionIndex) {

  var self = this;
  var skuSection;

  return self.browser.element.all(by.css('.w-product-sku-section'))

  .then(function(skuSections) {
    skuSection = skuSections[productIndex];
    return self.scrollToElement(skuSection);
  })

  .then(function() {
    return skuSection.all(by.css('.w-sku-price-category-select'));
  })

  .then(function(selectElements) {
    return selectElements[skuIndex].all(by.tagName('option'));
  })

  .then(function(options) {
    options[optionIndex].click();
  });
};

User.prototype.selectDataSourceFromReviewsAssignement = function(productIndex, dataSourceIndex) {

  var self = this;
  var formArray;

  var el;
  el = self.browser.element.all(by.css('.w-assign-reviews-form')).get(productIndex);

  return self.scrollToElement(el)
    .then(function() {
      return el.element(by.css('.w-assign-reviews-data-source-select')).all(by.tagName('option')).get(dataSourceIndex).click();
    });
};

User.prototype.waitForTextInElement = function(text, el) {
  var self = this;
  return self.browser.wait(EC.textToBePresentInElement(el, text), 1 * 10 * 1000);
};
User.prototype.waitForClickableElement = function(el) {
  var self = this;
  return self.browser.wait(EC.elementToBeClickable(el), 1 * 10 * 1000);
};
User.prototype.waitForSelectableElement = function(el) {
  var self = this;
  return self.browser.wait(EC.elementToBeSelected(el), 1 * 10 * 1000);
};
User.prototype.waitForPresentElement = function(el) {
  var self = this;
  return self.browser.wait(EC.presenceOf(el), 1 * 10 * 1000);
};
User.prototype.waitForVisibleElement = function(el, str) {
  var self = this;
  return self.waitForPresentElement(el)
    .then(function() {
      return self.browser.wait(EC.visibilityOf(el), 1 * 10 * 1000, str);
    });
};
User.prototype.select = function(el) {
  var self = this;
  return self.waitForSelectableElement(el)
    .then(function() {
      return self.waitForPresentElement(el)
    })
};
User.prototype.click = function(el) {
  var self = this;
  return self.waitForClickableElement(el)
    .then(function() {
      return el.click();
    }, function() {
      console.log('ELEMENT was not clickable');
    });
};



module.exports = User;