const tmi = require("tmi.js");
const { getSetting } = require("./settings");
const { incrementMessages } = require("./stats");
const { ensureUserForIdentity } = require("./users");

let client = null;

function parseChannels(raw) {
  return (raw || "")
    .split(/[,\s]+/)
    .map((entry) => entry.trim())
    .filter(Boolean)
    .map((entry) => (entry.startsWith("#") ? entry : `#${entry}`));
}

async function startTwitchBot({ commandRouter } = {}) {
  const username = getSetting("twitch_bot_username");
  const oauth = getSetting("twitch_bot_oauth");
  const channels = parseChannels(getSetting("twitch_channels"));
  if (!username || !oauth || !channels.length) {
    return null;
  }

  const password = oauth.startsWith("oauth:") ? oauth : `oauth:${oauth}`;
  client = new tmi.Client({
    options: { debug: false },
    identity: {
      username,
      password
    },
    channels
  });

  client.on("connected", (address, port) => {
    console.log(`Twitch bot connected to ${address}:${port}`);
  });

  client.on("message", async (channel, tags, message, self) => {
    if (self) {
      return;
    }
    const userId = tags["user-id"];
    if (!userId) {
      return;
    }
    const displayName = tags["display-name"] || tags.username;
    const profile = ensureUserForIdentity({
      provider: "twitch",
      providerUserId: userId,
      displayName
    });
    incrementMessages(profile.id);

    if (commandRouter) {
      await commandRouter.handleMessage({
        platform: "twitch",
        raw: message,
        user: profile,
        platformUser: {
          id: userId,
          displayName,
          username: tags.username
        },
        meta: { channel, tags, client },
        reply: async (content) => {
          try {
            await client.say(channel, content);
          } catch (error) {
            console.error("Twitch command reply failed", error);
          }
        }
      });
    }
  });

  await client.connect();
  return client;
}

async function stopTwitchBot() {
  if (client) {
    await client.disconnect();
    client = null;
  }
}

function getClient() {
  return client;
}

module.exports = {
  startTwitchBot,
  stopTwitchBot,
  getClient
};
