import axios from 'axios';
import { Notification } from '..';
import logger from '../../../logger';
import { getSettings } from '../../settings';
import type { NotificationAgent, NotificationPayload } from './agent';

enum EmbedColors {
  DEFAULT = 0,
  AQUA = 1752220,
  GREEN = 3066993,
  BLUE = 3447003,
  PURPLE = 10181046,
  GOLD = 15844367,
  ORANGE = 15105570,
  RED = 15158332,
  GREY = 9807270,
  DARKER_GREY = 8359053,
  NAVY = 3426654,
  DARK_AQUA = 1146986,
  DARK_GREEN = 2067276,
  DARK_BLUE = 2123412,
  DARK_PURPLE = 7419530,
  DARK_GOLD = 12745742,
  DARK_ORANGE = 11027200,
  DARK_RED = 10038562,
  DARK_GREY = 9936031,
  LIGHT_GREY = 12370112,
  DARK_NAVY = 2899536,
  LUMINOUS_VIVID_PINK = 16580705,
  DARK_VIVID_PINK = 12320855,
}

interface DiscordImageEmbed {
  url?: string;
  proxy_url?: string;
  height?: number;
  width?: number;
}

interface DiscordRichEmbed {
  title?: string;
  type?: 'rich'; // Always rich for webhooks
  description?: string;
  url?: string;
  timestamp?: string;
  color?: number;
  footer?: {
    text: string;
    icon_url?: string;
    proxy_icon_url?: string;
  };
  image?: DiscordImageEmbed;
  thumbnail?: DiscordImageEmbed;
  provider?: {
    name?: string;
    url?: string;
  };
  author?: {
    name?: string;
    url?: string;
    icon_url?: string;
    proxy_icon_url?: string;
  };
  fields?: {
    name: string;
    value: string;
    inline?: boolean;
  }[];
}

interface DiscordWebhookPayload {
  embeds: DiscordRichEmbed[];
  username: string;
  avatar_url?: string;
  tts: boolean;
}

class DiscordAgent implements NotificationAgent {
  public buildEmbed(
    type: Notification,
    payload: NotificationPayload
  ): DiscordRichEmbed {
    let color = EmbedColors.DEFAULT;
    let status = 'Unknown';

    switch (type) {
      case Notification.MEDIA_PENDING:
        color = EmbedColors.ORANGE;
        status = 'Pending Approval';
        break;
      case Notification.MEDIA_APPROVED:
        color = EmbedColors.PURPLE;
        status = 'Processing Request';
        break;
      case Notification.MEDIA_AVAILABLE:
        color = EmbedColors.GREEN;
        status = 'Available';
        break;
    }

    return {
      title: payload.subject,
      description: payload.message,
      color,
      timestamp: new Date().toISOString(),
      author: { name: 'Overseerr' },
      fields: [
        {
          name: 'Requested By',
          value: payload.notifyUser.username ?? '',
          inline: true,
        },
        {
          name: 'Status',
          value: status,
          inline: true,
        },
        // If we have extra data, map it to fields for discord notifications
        ...(payload.extra ?? []).map((extra) => ({
          name: extra.name,
          value: extra.value,
        })),
      ],
      thumbnail: {
        url: payload.image,
      },
    };
  }

  public shouldSend(type: Notification): boolean {
    const settings = getSettings();

    if (
      settings.notifications.agents.discord?.enabled &&
      settings.notifications.agents.discord?.options?.webhookUrl
    ) {
      return true;
    }

    return false;
  }

  public async send(
    type: Notification,
    payload: NotificationPayload
  ): Promise<boolean> {
    const settings = getSettings();
    logger.debug('Sending discord notification', { label: 'Notifications' });
    try {
      const webhookUrl =
        settings.notifications.agents.discord?.options?.webhookUrl;

      if (!webhookUrl) {
        return false;
      }

      await axios.post(webhookUrl, {
        username: 'Overseerr',
        embeds: [this.buildEmbed(type, payload)],
      } as DiscordWebhookPayload);

      return true;
    } catch (e) {
      logger.error('Error sending Discord notification', {
        label: 'Notifications',
        message: e.message,
      });
      return false;
    }
  }
}

export default DiscordAgent;
