import kue from 'kue';
import debuglog from 'debug';

import services from '../lib/services.js';
import render from '../lib/render.js';
import models from '../models/index.cjs';
import { find, create } from '../lib/share.js';

const debug = debuglog('combine.fm:share');

const queue = kue.createQueue({
  redis: process.env.REDIS_URL,
});

export default async function (ctx, serviceId, type, itemId, format) {
  ctx.assert(type === 'album' || type === 'track', 400, { error: 'Invalid type' });

  let share = await models[type].findOne({
    where: {
      externalId: itemId,
    },
    include: [
      { model: models.match },
      { model: models.artist },
    ],
  });

  if (!share) {
    const matchedService = services.find(service => serviceId === service.id);
    const music = await matchedService.lookupId(itemId, type);

    ctx.assert(music, 400, { error: { message: 'No supported music found at that link :(' } });

    share = await find(music);

    if (!share) {
      share = await create(music);

      services.forEach((service) => {
        if (service.id !== share.service) {
          const job = queue.create('search', { title: `Matching ${share.name} on ${service.id}`, share, service })
            .attempts(3)
            .backoff({ type: 'exponential' })
            .save((err) => {
              debug(err || `JobID: ${job.id}`);
            });
        }
      });
    }
  }

  ctx.assert(share, 404);

  const unmatched = services.filter(service =>
    !share.matches.find(match => match.service === service.id));

  share = share.toJSON();
  share.matches = share.matches.concat(unmatched.map((service) => {
    return {
      service: service.id,
      matching: true,
    };
  }));
  share.matches = share.matches.sort(a => !a.externalId);

  if (format === 'json') {
    ctx.body = share;
  } else {
    const initialState = {
      item: share,
      services: services.map(service => service.id),
      share: true,
    };

    const url = `/${serviceId}/${type}/${itemId}`;

    const html = await render(url, initialState);

    const head = {
      share,
      title: `${share.name} by ${share.artist.name}`,
      shareUrl: `${ctx.request.origin}${url}`,
      image: share.matches.find(el => el.service === share.service).artworkLarge,
    };

    await ctx.render('index', {
      initialState,
      share,
      head,
      html,
    });
  }
}