import type { Customer } from '../billing/middleware.js';
import type { OAuthCredentials } from '../multitenancy/credential-store.js';
import { createToolAudit } from '../multitenancy/audit-log.js';

const DISCORD_API_BASE = 'https://discord.com/api/v10';

function getEnvToken(account: string): string {
  const envKey = `DISCORD_${account.toUpperCase()}_BOT_TOKEN`;
  return process.env[envKey] ?? '';
}

async function resolveToken(args: { account?: string }, customer?: Customer): Promise<string> {
  if (customer) {
    const creds = await customer.getCredential<OAuthCredentials>('discord');
    if (!creds) throw new Error('Discord not connected for this account');
    return creds.accessToken;
  }
  const token = getEnvToken(args.account ?? 'default');
  if (!token) throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
  return token;
}

async function discordRequest(
  token: string,
  endpoint: string,
  method: 'GET' | 'POST' = 'GET',
  body?: unknown
) {
  const url = `${DISCORD_API_BASE}${endpoint}`;
  const res = await fetch(url, {
    method,
    headers: {
      'Authorization': `Bot ${token}`,
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
    signal: AbortSignal.timeout(15000),
  });

  if (!res.ok) {
    const error = await res.text();
    throw new Error(`Discord API error (${res.status}): ${error}`);
  }

  return res.json();
}

export async function getMe(
  args: { account?: string },
  customer?: Customer
): Promise<{ id: string; username: string; bot: boolean }> {
  const token = await resolveToken(args, customer);
  return discordRequest(token, '/users/@me');
}

export async function getGuilds(
  args: { account?: string },
  customer?: Customer
): Promise<Array<{ id: string; name: string; icon?: string }>> {
  const token = await resolveToken(args, customer);
  return discordRequest(token, '/users/@me/guilds');
}

export async function getChannels(
  args: { guild_id: string; account?: string },
  customer?: Customer
): Promise<Array<{ id: string; name: string; type: number }>> {
  const token = await resolveToken(args, customer);
  return discordRequest(token, `/guilds/${args.guild_id}/channels`);
}

export async function sendMessage(
  args: { channel_id: string; content: string; account?: string },
  customer?: Customer
): Promise<{ id: string; channel_id: string }> {
  const audit = customer ? createToolAudit(customer.id, 'discord:sendMessage') : null;
  const auditArgs = { channel_id: args.channel_id };
  const token = await resolveToken(args, customer);

  try {
    const result = await discordRequest(token, `/channels/${args.channel_id}/messages`, 'POST', {
      content: args.content,
    });
    if (audit) await audit.success(auditArgs);
    return result;
  } catch (err) {
    if (audit) await audit.error(auditArgs, String(err));
    throw err;
  }
}

export async function getMessages(
  args: { channel_id: string; limit?: number; account?: string },
  customer?: Customer
): Promise<Array<{
  id: string;
  content: string;
  author: { username: string; id: string };
  timestamp: string;
}>> {
  const token = await resolveToken(args, customer);
  const limit = args.limit ?? 10;
  return discordRequest(token, `/channels/${args.channel_id}/messages?limit=${limit}`);
}
