import type { Redis } from 'ioredis';
import { getFunConfig } from './config.js';

export class FunMediaError extends Error {
  constructor(public readonly code: 'disabled' | 'fetch_failed') {
    super(code);
    this.name = 'FunMediaError';
  }
}

type MemeApiResponse = {
  url?: string;
  title?: string;
};

type CatApiResponse = Array<{ url?: string }>;

type DogApiResponse = {
  message?: string;
  status?: string;
};

export async function assertMediaEnabled(redis: Redis, guildId: string): Promise<void> {
  const config = await getFunConfig(redis, guildId);
  if (!config.mediaEnabled) {
    throw new FunMediaError('disabled');
  }
}

export async function fetchMeme(): Promise<{ url: string; title: string }> {
  const response = await fetch('https://meme-api.com/gimme');
  if (!response.ok) {
    throw new FunMediaError('fetch_failed');
  }
  const data = (await response.json()) as MemeApiResponse;
  if (!data.url) {
    throw new FunMediaError('fetch_failed');
  }
  return { url: data.url, title: data.title ?? 'Meme' };
}

export async function fetchCatImage(): Promise<string> {
  const response = await fetch('https://api.thecatapi.com/v1/images/search');
  if (!response.ok) {
    throw new FunMediaError('fetch_failed');
  }
  const data = (await response.json()) as CatApiResponse;
  const url = data[0]?.url;
  if (!url) {
    throw new FunMediaError('fetch_failed');
  }
  return url;
}

export async function fetchDogImage(): Promise<string> {
  const response = await fetch('https://dog.ceo/api/breeds/image/random');
  if (!response.ok) {
    throw new FunMediaError('fetch_failed');
  }
  const data = (await response.json()) as DogApiResponse;
  if (data.status !== 'success' || !data.message) {
    throw new FunMediaError('fetch_failed');
  }
  return data.message;
}
