const { getTwitchEntitlement } = require("./command-platform");

const REQUIREMENTS = ["public", "follower", "subscriber", "vip", "mod", "editor", "streamer"];

async function checkCommandRequirement(ctx, requirement = {}) {
  const role = REQUIREMENTS.includes(requirement.role) ? requirement.role : "public";
  if (role === "public") return { allowed: true };
  const flags = localRoleFlags(ctx);
  if (flags.streamer) return { allowed: true };
  if (role === "streamer") return denied(role);
  if (role === "editor") {
    if (flags.editor) return { allowed: true };
    return checkRemoteTwitch(ctx, role, requirement);
  }
  if (role === "mod") return flags.mod || flags.editor ? { allowed: true } : denied(role);
  if (role === "vip") return flags.vip || flags.mod || flags.editor ? { allowed: true } : denied(role);
  if (role === "subscriber") {
    const minimumTier = Math.max(1, Math.min(3, Number(requirement.subscriberTier) || 1));
    if ((flags.subscriberTier || 0) >= minimumTier || flags.vip || flags.mod || flags.editor) return { allowed: true };
    return checkRemoteTwitch(ctx, role, { subscriberTier: minimumTier });
  }
  if (role === "follower") {
    if (flags.follower || flags.subscriberTier || flags.vip || flags.mod || flags.editor) return { allowed: true };
    return checkRemoteTwitch(ctx, role, requirement);
  }
  return denied(role);
}

function localRoleFlags(ctx) {
  if (ctx.platform === "twitch") {
    const tags = ctx.meta?.tags || {};
    const badges = tags.badges || {};
    const streamer = Boolean(badges.broadcaster) || sameTwitchChannel(ctx);
    return {
      streamer,
      editor: false,
      mod: streamer || Boolean(tags.mod || badges.moderator),
      vip: Boolean(badges.vip),
      subscriberTier: tags.subscriber || badges.subscriber ? 1 : 0,
      follower: false
    };
  }
  if (ctx.platform === "youtube") {
    const author = ctx.meta?.author || {};
    const streamer = Boolean(author.isChatOwner);
    return {
      streamer,
      editor: streamer,
      mod: streamer || Boolean(author.isChatModerator),
      vip: false,
      subscriberTier: author.isChatSponsor ? 1 : 0,
      follower: false
    };
  }
  if (ctx.platform === "discord") {
    const message = ctx.meta?.message;
    const member = message?.member;
    const guild = message?.guild;
    const roleNames = member?.roles?.cache
      ? Array.from(member.roles.cache.values()).map((role) => String(role.name || "").toLowerCase())
      : [];
    const permissions = member?.permissions;
    const has = (permission) => {
      try { return Boolean(permissions?.has?.(permission)); } catch { return false; }
    };
    const streamer = Boolean(guild?.ownerId && guild.ownerId === message?.author?.id);
    const administrator = has("ADMINISTRATOR") || has(8n);
    return {
      streamer,
      editor: streamer || administrator || has("MANAGE_GUILD"),
      mod: streamer || administrator || has("MODERATE_MEMBERS") || has("MANAGE_MESSAGES"),
      vip: roleNames.some((name) => name === "vip"),
      subscriberTier: roleNames.some((name) => /subscriber|supporter|member/.test(name)) ? 1 : 0,
      follower: false
    };
  }
  return { streamer: false, editor: false, mod: false, vip: false, subscriberTier: 0, follower: false };
}

async function checkRemoteTwitch(ctx, role, requirement) {
  if (ctx.platform !== "twitch") return denied(role, true);
  try {
    const allowed = await getTwitchEntitlement(ctx, role, requirement.subscriberTier);
    return allowed ? { allowed: true } : denied(role);
  } catch (error) {
    return {
      allowed: false,
      reason: `Lumi could not verify the required ${labelRequirement(role, requirement.subscriberTier)} status. An admin may need to reconnect Twitch with the matching permission.`,
      verificationError: error?.message || "Verification failed."
    };
  }
}

function denied(role, unsupported = false) {
  const status = labelRequirement(role);
  return {
    allowed: false,
    reason: unsupported
      ? `${status} access cannot be verified on this platform.`
      : `This command is limited to ${status}.`
  };
}

function labelRequirement(role, subscriberTier) {
  if (role === "public") return "everyone";
  if (role === "subscriber" && Number(subscriberTier) > 1) return `Tier ${subscriberTier}+ subscribers`;
  return ({
    follower: "followers",
    subscriber: "subscribers or members",
    vip: "VIPs",
    mod: "moderators",
    editor: "editors",
    streamer: "the streamer"
  })[role] || role;
}

function sameTwitchChannel(ctx) {
  const channel = String(ctx.meta?.channel || "").replace(/^#/, "").toLowerCase();
  const username = String(ctx.platformUser?.username || "").toLowerCase();
  return Boolean(channel && username && channel === username);
}

module.exports = {
  REQUIREMENTS,
  checkCommandRequirement,
  labelRequirement,
  localRoleFlags
};
