import { test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import moduleForComponent from 'web-client/tests/helpers/module-for-component';
import Service from 'ember-service';
import RSVP from 'rsvp';
import wait from 'ember-test-helpers/wait';

const TEST_CODE = 'TEST-CONTENT-CODE';
const CLAIM_INSTRUCTION = 'the offer claim instructions mate!';

let requestCalls = [];

const AuthenticatedSession = Service.extend({
  isAuthenticated: true,
  userData: {
    login: 'wittyusername',
    id: '123'
  }
});

const APIStub = Service.extend({
  request(method, url, payload) {
    requestCalls.push({ method, url, payload });
    return RSVP.resolve({
      claimData: TEST_CODE,
      contentClaimInstruction: CLAIM_INSTRUCTION
    });
  }
});

moduleForComponent('twitch-prime/offer-detail', 'Integration | Component | twitch-prime/offer-detail', {

  beforeEach() {
    requestCalls.length = 0;
    this.inject.service('claimOffer');
    this.set('claimOffer.offerIdToCode', {});
  }
});

test('it renders with a title', function(assert) {
  let offerModel = this.server.create('offer', {
    offerTitle: 'Mock Offer Title'
  });
  this.set('offer', offerModel);

  this.render(hbs`{{twitch-prime/offer-detail offer=offer}}`);

  assert.elementText($('.offer-item__balloon h4'), 'Mock Offer Title');
});

test('without prime show the "try prime" call to action button', function(assert) {
  this.render(hbs`{{twitch-prime/offer-detail hasPrime=false}}`);

  assert.elementText($('.offer-item__upsell-header'), 'Claim with Twitch Prime');
});


test('with prime show the "get code" button for claim code offers', function(assert) {
  this.render(hbs`{{twitch-prime/offer-detail hasPrime=true}}`);

  assert.elementText($('.offer-item__instructions button'), 'Get Code');
});

test('with prime show the "claim offer" button for DIRECT_ENTITLEMENT offers', function(assert) {
  let offerModel = this.server.create('offer', {
    offerTitle: 'Mock Offer Title',
    contentDeliveryMethod: 'DIRECT_ENTITLEMENT'
  });

  this.set('offer', offerModel);

  this.render(hbs`{{twitch-prime/offer-detail offer=offer hasPrime=true}}`);

  assert.elementText($('.offer-item__instructions button'), 'Claim Offer');
});

test('claim DIRECT_ENTITLEMENT offers', function(assert) {
  assert.expect(1);
  this.register('service:session', AuthenticatedSession);

  let offerUrl = 'fuel-is-going-to-be-great';
  let claim = {
    type: 'DIRECT_ENTITLEMENT',
    claimData: offerUrl
  };

  this.server.post('http://api.twitch.tv/api/premium/offers/:offer_id/claim', function(schema, request) {
    requestCalls.push(request);
    return claim;
  });

  let offerModel = this.server.create('offer', {
    offerTitle: 'Fuel Title',
    id: 'TEST-OFFER-ID',
    contentDeliveryMethod: 'DIRECT_ENTITLEMENT'
  });

  this.set('offer', offerModel);

  this.render(hbs`{{twitch-prime/offer-detail hasPrime=true offer=offer}}`);

  this.$('.offer-item__instructions button').click();

  return wait().then(() => {
    assert.equal(requestCalls.length, 1, 'The api service is called once.');
  });

});

test('it claims the code from the right URL', function(assert) {
  assert.expect(5);

  this.register('service:session', AuthenticatedSession);
  this.register('service:api', APIStub);

  let offerModel = this.server.create('offer', {
    offerTitle: 'Unrelated Title',
    id: 'TEST-OFFER-ID',
    contentClaimInstruction: 'NOT THESE INSTRUCTIONS'
  });

  this.set('offer', offerModel);
  this.render(hbs`{{twitch-prime/offer-detail hasPrime=true offer=offer}}`);
  this.$('.offer-item__instructions button').click();

  return wait().then(() => {
    assert.equal(requestCalls.length, 1, 'The api service is called once.');
    let request = requestCalls[0];
    assert.equal(request.method, 'post', 'The API request uses POST');
    assert.equal(request.url, '/api/premium/offers/TEST-OFFER-ID/claim', 'The API request uses the right URL.');
    assert.elementVal(this.$('.copyable-item .copy-text'), TEST_CODE, 'The input displays the correct code.');
    assert.elementText(this.$('[data-test-offer-claim-instruction]'), CLAIM_INSTRUCTION, 'Displays the offer claim instructions.');
  });
});

test('it claims the code automatically if it\'s already been claimed', function(assert) {
  assert.expect(1);

  this.register('service:session', AuthenticatedSession);
  this.register('service:api', APIStub);

  let offerModel = this.server.create('offer', {
    offerTitle: 'Unrelated Title',
    id: 'TEST-OFFER-ID'
  });

  let claimedOfferIds = [`${offerModel.id}-123`]; //claimed offer ids are `offerId-tuid`

  this.set('claimedOfferIds', claimedOfferIds);
  this.set('offer', offerModel);
  this.render(hbs`{{twitch-prime/offer-detail claimedOfferIds=claimedOfferIds hasPrime=true offer=offer}}`);

  return wait().then(() => {
    assert.equal($('.copyable-item .copy-text').val(), TEST_CODE, 'The input displays the correct code.');
  });
});
