import type { QuickEntry, QuickReaction, QuickSeparator } from './types';

export function isSeparator(entry: QuickEntry): entry is QuickSeparator {
  return 'separator' in entry;
}

export function normaliseQuick(entries: readonly QuickEntry[]): QuickEntry[] {
  const seen = new Set<string>();
  const out: QuickEntry[] = [];
  for (const entry of entries) {
    if (isSeparator(entry)) {
      const last = out[out.length - 1];
      if (last && !isSeparator(last)) out.push(entry);
      continue;
    }
    if (seen.has(entry.key)) continue;
    seen.add(entry.key);
    out.push(entry);
  }
  const last = out[out.length - 1];
  if (last && isSeparator(last)) out.pop();
  return out;
}

export function parseQuickReactions(raw: unknown): QuickEntry[] | null {
  if (typeof raw !== 'object' || raw === null) return null;
  const list = (raw as Record<string, unknown>)['reactions'];
  if (!Array.isArray(list)) return null;
  const entries: QuickEntry[] = [];
  for (const item of list) {
    if (typeof item !== 'object' || item === null) continue;
    const { key, shortcode, separator } = item as Record<string, unknown>;
    if (separator === true) {
      entries.push({ separator: true });
      continue;
    }
    if (typeof key !== 'string' || !key) continue;
    entries.push({ key, shortcode: typeof shortcode === 'string' ? shortcode : null });
  }
  return normaliseQuick(entries);
}

export function quickGroups(entries: readonly QuickEntry[]): QuickReaction[][] {
  const groups: QuickReaction[][] = [];
  let group: QuickReaction[] = [];
  for (const entry of entries) {
    if (!isSeparator(entry)) {
      group.push(entry);
      continue;
    }
    if (group.length > 0) groups.push(group);
    group = [];
  }
  if (group.length > 0) groups.push(group);
  return groups;
}

export function quickColumns(groups: readonly QuickReaction[][], perRow: number): number {
  return groups.reduce((cols, group) => Math.max(cols, Math.min(group.length, perRow)), 0);
}

export function sameQuick(a: readonly QuickEntry[], b: readonly QuickEntry[]): boolean {
  return (
    a.length === b.length &&
    a.every((entry, i) => {
      const other = b[i];
      return isSeparator(entry) ? isSeparator(other) : !isSeparator(other) && entry.key === other.key;
    })
  );
}
