import { Response } from 'ember-cli-mirage';
import supports from 'web-client/mirage/utils/supports';
import { parseQueryParams } from 'web-client/utilities/url-params';
import { thumbnailPreviewURL } from 'web-client/mirage/serializers/video';
import { assign } from 'ember-platform';
import { UPLOAD_TYPE_PARAM } from 'web-client/utilities/video/types';
import { normalizeVideoId } from 'web-client/utilities/normalize-video-id';

export default function vodUploadRoutes(server) {
  server.post('https://api.twitch.tv/kraken/videos', function(schema, request) {
    let channelName = request.queryParams.channel_id;
    let channel = schema.channels.where({ name: channelName }).models[0];
    let payload = parseQueryParams(request.requestBody);

    if (!channel) {
      throw new Error(`No channel found with id: ${channelName}`);
    }

    let videoProperties = assign({
      channel,
      status: 'created',
      upload_token: 'upload-token',
      title: null,
      description: null,
      language: null,
      game: null,
      viewable: 'private',
      tag_list: ''
    }, payload);

    return schema.videos.create(videoProperties);
  });

  server.get(
    'https://api.twitch.tv/api/channels/:channelName/video_manager/uploads',
    apiHandler(function({ videos }, { params, queryParams }) {
      let { channelName } = params;
      let { status } = queryParams;
      let statuses = status.split(',');

      return videos.all().filter(video => {
        return video.channel.name === channelName &&
               video.broadcast_type === UPLOAD_TYPE_PARAM &&
               statuses.includes(video.status);
      });
    })
  );

  // This option can be used to control the timing of the video upload
  server.options.videoFileUploadTiming = null;

  server.put('https://uploads.twitch.tv/upload/:videoId', function(schema, request) {
    let id = normalizeVideoId(request.params.videoId);

    let video = schema.videos.find(id);
    video.createVideoUpload({ request, file: request.requestBody, isComplete: false });
    video.save();

    return new Response(200, {}, {});
  }, {
    timing() {
      return server.options.videoFileUploadTiming;
    }
  });

  server.post('https://uploads.twitch.tv/upload/:videoId/complete', function(schema, request) {
    let id = normalizeVideoId(request.params.videoId);

    let video = schema.videos.find(id);
    video.videoUpload.update('isComplete', true);

    return new Response(200, {}, {});
  });

  server.put('https://api.twitch.tv/api/vods/:id', apiHandler(function(schema, request) {
    let id = request.params.id;
    let payload = parseQueryParams(request.requestBody);
    let video = schema.videos.find(id);
    video.update(payload);

    return video;
  }));

  server.post(`https://api.twitch.tv/api/vods/:videoId/upload_thumbnail`, apiHandler(function(schema, request) {
    let formData = request.requestBody;
    let id = request.params.videoId;
    let video = schema.videos.find(id);

    let data = {};

    if (supports.formDataGet) {
      data = {
        crop_x: formData.get('crop_x'),
        crop_y: formData.get('crop_y'),
        crop_h: formData.get('crop_h'),
        crop_w: formData.get('crop_w'),
        image: formData.get('image')
      };

    }

    video.createCustomThumbnail(data);
    video.save();

    return {
      thumbnails: [{
        type: 'custom',
        url: thumbnailPreviewURL(video)
      }]
    };
  }));

  server.delete('https://api.twitch.tv/kraken/videos/:id', apiHandler(function({ videos }, request) {
    videos.find(request.params.id).destroy();

    return new Response(200, {}, { ok: true });
  }));

  server.get('/discovery/search', function() {
    return [];
  });
}

// Add a check to ensure that the Client-ID header is set for each request.
function apiHandler(handlerFunction) {
  return function(schema, request) {
    if (!request.requestHeaders['Client-ID']) {
      return new Response(400, {}, {
        error: 'Bad Request',
        status: 400,
        message: 'No client id specified'
      });
    }

    return handlerFunction(schema, request);
  };
}
