import type { ChannelStatus, ChatMessage, InboundKickEvent } from "../types.ts";

type JsonObject = Record<string, unknown>;

const safeHexColor = (value: unknown): string | undefined => {
  const raw = String(value ?? "").trim();
  return /^#?[0-9a-f]{6}$/i.test(raw) ? `#${raw.replace("#", "").toUpperCase()}` : undefined;
};

const safeBadgeImage = (badge: JsonObject): string | undefined => {
  const image = (badge.image ?? badge.icon) as JsonObject | string | undefined;
  const candidate = String(
    badge.image_url ?? badge.imageUrl ?? badge.icon_url ?? badge.iconUrl
      ?? (typeof image === "object" && image !== null ? image.url ?? image.src : image)
      ?? ""
  ).trim();
  return /^https:\/\//i.test(candidate) ? candidate.slice(0, 1000) : undefined;
};

export const parseInboundPayload = (event: InboundKickEvent): JsonObject => {
  const value = JSON.parse(event.payload_json) as unknown;
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    throw new Error("Payload webhook Kick invalide.");
  }
  return value as JsonObject;
};

export const toChatMessage = (
  event: InboundKickEvent,
  channel: ChannelStatus,
  payload: JsonObject
): ChatMessage | null => {
  if (event.event_type !== "chat.message.sent") return null;
  const sender = (payload.sender ?? {}) as JsonObject;
  const identity = (sender.identity ?? {}) as JsonObject;
  const badges = Array.isArray(identity.badges) ? identity.badges : [];
  const roles = badges
    .map((badge) => String((badge as JsonObject).type ?? "").toLowerCase())
    .filter(Boolean);
  const badgeDetails = badges
    .map((value) => {
      const badge = (value && typeof value === "object" ? value : {}) as JsonObject;
      const type = String(badge.type ?? badge.name ?? badge.slug ?? "").trim().toLowerCase();
      if (!type) return null;
      const title = String(badge.text ?? badge.title ?? badge.name ?? type).trim().slice(0, 120) || type;
      const imageUrl = safeBadgeImage(badge);
      return imageUrl ? { type, title, image_url: imageUrl } : { type, title };
    })
    .filter((badge): badge is NonNullable<typeof badge> => badge !== null);
  // The official Chat Message Sent webhook names this username_color.
  // Keep color as a fallback for older deliveries.
  const color = safeHexColor(identity.username_color ?? identity.color);
  const content = String(payload.content ?? "").trim();
  const senderId = String(sender.user_id ?? "");
  if (!content || !senderId) return null;
  return {
    event_id: String(payload.message_id ?? event.kick_message_id),
    channel_id: channel.channel_id,
    kick_channel_id: channel.kick_channel_id,
    kick_chatroom_id: channel.kick_chatroom_id,
    content,
    sender: {
      kick_user_id: senderId,
      username: String(sender.username ?? "viewer"),
      roles: [...new Set(roles)],
      ...(color ? { color } : {}),
      ...(badgeDetails.length ? { badges: badgeDetails } : {})
    },
    created_at: String(payload.created_at ?? new Date().toISOString())
  };
};
