const { getSetting } = require("./settings");

const YOUTUBE_SCOPES = [
  "https://www.googleapis.com/auth/youtube",
  "https://www.googleapis.com/auth/youtube.force-ssl",
  "https://www.googleapis.com/auth/youtube.readonly",
  "https://www.googleapis.com/auth/youtube.channel-memberships.creator"
];

function getDiscordRedirectUri(override) {
  return override || getSetting("discord_redirect_uri", null);
}

function buildDiscordAuthUrl(state, redirectOverride) {
  const clientId = getSetting("discord_client_id");
  const redirectUri = getDiscordRedirectUri(redirectOverride);
  const params = new URLSearchParams({
    client_id: clientId || "",
    redirect_uri: redirectUri || "",
    response_type: "code",
    scope: "identify guilds guilds.members.read",
    state
  });
  return `https://discord.com/api/oauth2/authorize?${params.toString()}`;
}

async function exchangeDiscordCode(code, redirectOverride) {
  const clientId = getSetting("discord_client_id");
  const clientSecret = getSetting("discord_client_secret");
  const redirectUri = getDiscordRedirectUri(redirectOverride);
  const body = new URLSearchParams({
    client_id: clientId || "",
    client_secret: clientSecret || "",
    grant_type: "authorization_code",
    code,
    redirect_uri: redirectUri || ""
  });

  const response = await fetch("https://discord.com/api/oauth2/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body
  });

  if (!response.ok) {
    throw new Error(`Discord token exchange failed: ${response.status}`);
  }

  return response.json();
}

async function fetchDiscordUser(accessToken) {
  const response = await fetch("https://discord.com/api/users/@me", {
    headers: { Authorization: `Bearer ${accessToken}` }
  });
  if (!response.ok) {
    throw new Error(`Discord user fetch failed: ${response.status}`);
  }
  return response.json();
}

async function fetchDiscordGuildMember(accessToken, guildId) {
  const response = await fetch(
    `https://discord.com/api/users/@me/guilds/${guildId}/member`,
    {
      headers: { Authorization: `Bearer ${accessToken}` }
    }
  );
  if (!response.ok) {
    return null;
  }
  return response.json();
}

function buildTwitchAuthUrl(state, redirectOverride) {
  const clientId = getSetting("twitch_client_id");
  const redirectUri = redirectOverride || getSetting("twitch_redirect_uri");
  const params = new URLSearchParams({
    client_id: clientId || "",
    redirect_uri: redirectUri || "",
    response_type: "code",
    scope: "user:read:email",
    state
  });
  return `https://id.twitch.tv/oauth2/authorize?${params.toString()}`;
}

function buildTwitchEventAuthUrl(state, redirectOverride) {
  const clientId = getSetting("twitch_client_id");
  const redirectUri = redirectOverride || getSetting("twitch_redirect_uri");
  const params = new URLSearchParams({
    client_id: clientId || "",
    redirect_uri: redirectUri || "",
    response_type: "code",
    scope: "moderator:read:followers channel:read:subscriptions",
    state,
    force_verify: "true"
  });
  return `https://id.twitch.tv/oauth2/authorize?${params.toString()}`;
}

async function exchangeTwitchCode(code, redirectOverride) {
  const clientId = getSetting("twitch_client_id");
  const clientSecret = getSetting("twitch_client_secret");
  const redirectUri = redirectOverride || getSetting("twitch_redirect_uri");
  const params = new URLSearchParams({
    client_id: clientId || "",
    client_secret: clientSecret || "",
    code,
    grant_type: "authorization_code",
    redirect_uri: redirectUri || ""
  });
  const response = await fetch(
    `https://id.twitch.tv/oauth2/token?${params.toString()}`,
    { method: "POST" }
  );
  if (!response.ok) {
    throw new Error(`Twitch token exchange failed: ${response.status}`);
  }
  return response.json();
}

async function fetchTwitchUser(accessToken) {
  const clientId = getSetting("twitch_client_id");
  const response = await fetch("https://api.twitch.tv/helix/users", {
    headers: {
      "Client-Id": clientId || "",
      Authorization: `Bearer ${accessToken}`
    }
  });
  if (!response.ok) {
    throw new Error(`Twitch user fetch failed: ${response.status}`);
  }
  const data = await response.json();
  return data.data?.[0] || null;
}

function buildYouTubeAuthUrl(state, redirectOverride, options = {}) {
  const clientId = getSetting("youtube_client_id");
  const redirectUri = redirectOverride || getSetting("youtube_redirect_uri");
  const scopes = options.scopes || YOUTUBE_SCOPES;
  const params = new URLSearchParams({
    client_id: clientId || "",
    redirect_uri: redirectUri || "",
    response_type: "code",
    scope: scopes.join(" "),
    state,
    access_type: "offline",
    include_granted_scopes: "true"
  });
  if (options.prompt) {
    params.set("prompt", options.prompt);
  }
  return `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
}

async function exchangeYouTubeCode(code, redirectOverride) {
  const clientId = getSetting("youtube_client_id");
  const clientSecret = getSetting("youtube_client_secret");
  const redirectUri = redirectOverride || getSetting("youtube_redirect_uri");
  const body = new URLSearchParams({
    client_id: clientId || "",
    client_secret: clientSecret || "",
    grant_type: "authorization_code",
    code,
    redirect_uri: redirectUri || ""
  });
  const response = await fetch("https://oauth2.googleapis.com/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body
  });
  if (!response.ok) {
    throw new Error(`YouTube token exchange failed: ${response.status}`);
  }
  return response.json();
}

async function fetchYouTubeChannel(accessToken) {
  const response = await fetch(
    "https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true",
    { headers: { Authorization: `Bearer ${accessToken}` } }
  );
  if (!response.ok) {
    throw new Error(`YouTube channel fetch failed: ${response.status}`);
  }
  const data = await response.json();
  return data.items?.[0] || null;
}

module.exports = {
  buildDiscordAuthUrl,
  exchangeDiscordCode,
  fetchDiscordUser,
  fetchDiscordGuildMember,
  buildTwitchAuthUrl,
  buildTwitchEventAuthUrl,
  exchangeTwitchCode,
  fetchTwitchUser,
  buildYouTubeAuthUrl,
  exchangeYouTubeCode,
  fetchYouTubeChannel
};
