const standardEntity = require("../standardEntity");
const resourceEntity = require("../resourceEntity");
const hapi   = require("../hapi");
const Logger = require("../Logger");
const _ = require("lodash");
const category = require("./category")
const ping = require("./ping")
const {zip, unzip, downloadWebsite} = require('./zip')

async function publish(api, argv) {
  const {id, wait} = argv;
  if(!wait) return await api.website.publish({id});
  const log = Logger(argv);

  log.info(await api.website.publish({id}))

  let removeListener = () => {}
  const res = await Promise.race([
    new Promise(resolve => setTimeout(() => resolve("Timeout expired"), 60000)),
    new Promise(resolve => {
      function onNotify(data)  {
        //worker: 'SiteRender', id: _id, action, message, info, website
        log.info(data)
        resolve("Finished")
      }
      removeListener = () => api.removeEventListener("notify", onNotify)
      api.on("notify", onNotify)
    })
  ]);
  removeListener();
  return res;
}

const publishAsTemplate = (api, {id}) => api.website.publishAsTemplate({id});
const unpublishAsTemplate = (api, {id}) => api.website.unpublishAsTemplate({id});

module.exports = yargs => category(yargs).command({
  command: "website",
  desc: "Website/page support",
  builder: yargs => standardEntity("website")(yargs).command({
    command: "addPage <id> <data>",
    desc: "Append page to website",
    handler: hapi(async (api, {id, data}) => {
      const {data: {__v}} = await api.website.get({id, query: {select: "__v"}});
      return await api.website.addPage({id, __v, data: JSON.parse(data)});
    })
  }).command({
    command: "removePage <id...>",
    desc: "Append pages from website",
    builder: yargs => yargs.array("id"),
    handler: hapi(async (api, {id}) => {
      const {data: {__v}} = await api.website.get({id, query: {select: "__v"}});
      if(id.length == 1) return await api.website.removePage({id: id[0], __v});
      return (
        await Promise.all(_.uniq(id).map(id => api.website.removePage({id, __v})))
      ).reduce((acc, val) => (acc.data.n += _.get(val, "data.n", 0), acc), {data: {n: 0}});
    })
  }).command({
    command: "getPage <id> <pageId>",
    desc: "Get page",
    handler: hapi(async (api, {id, pageId}) => api.website.getPage({id, pageId}))
  }).command({
    command: "addBlock <id> <location> <blockId>",
    desc: "Append block to header or footer (location: header|footer)",
    builder: yargs => yargs.choices("location", ['header', 'footer']),
    handler: hapi((api, {id, location, blockId}) => api.block.add({data: {
      website: id, location, source: blockId,
    }}))
  }).command({
    command: "addBlockToPage <id> <pageId> <blockId>",
    desc: "Append block to page",
    builder: yargs => yargs.default('value', 'true'),
    handler: hapi((api, {id, pageId, blockId}) =>
      api.block.add({data: {website: id, location: `WebsitePage:${pageId}`, source: blockId}})
    )
  }).command({
    command: "publish <id>",
    desc: "Publish website",
    builder: yargs => yargs.option("wait", {boolean: true, alias: "w", desc:"Wait for finish"}),
    handler: hapi(publish)
  }).command({
    command: "publishAsTemplate <id>",
    desc: "Create website template ",
    handler: hapi(publishAsTemplate)
  }).command({
    command: "unpublishAsTemplate <id>",
    desc: "Remove website template ",
    handler: hapi(unpublishAsTemplate)
  }).command({
    command: "resource",
    desc: "Resource support",
    builder: resourceEntity("website"),
    handler() {yargs.showHelp()}
  }).command({
    command: "zip [id]", desc: "zip website",
    builder: yargs => yargs.option("output", {alias: "o", desc: "output to file", string: true}),
    handler: hapi(zip)
  }).command({
    command: "unzip <filename>", desc: "unzip website.zip to new one. you have to define target owner or website",
    builder: yargs => yargs
      .option("website", {alias: "w", desc: "target website id", string: true})
      .option("owner", {alias: "o", desc: "target user id", string: true}),
    handler: hapi(unzip)
  }).command({
    command: "download <id>", desc: 'get website html. Use something like "python3 -m http.server 8080" to view site',
    builder: yargs => yargs.option("zipoutput", {alias: "z", desc: "output to zip file", string: true}),
    handler: hapi(downloadWebsite)
  }).command({
    command: "ping", desc: "ping user's domains access",
    handler: hapi(ping)
  }),
  handler() {yargs.showHelp()}
})
