import { mapEvent } from './mappers.js';

/**
 * Mehrere ATTACHMENT-DB-Zeilen pro Kalendertag (lokal) zu einem Listeneintrag zusammenführen.
 * @param {Array<Record<string, unknown>>} rows – SELECT * FROM events (bereits sortiert)
 * @param {Map<string, Array<Record<string, unknown>>>} byEvent – event_id → ticket_attachments-Zeilen
 * @param {{ prepare: (sql: string) => { get: (a: unknown) => { d?: string } | undefined } }} db
 */
export function mergeAttachmentEventsForApi(rows, byEvent, db) {
  const dayKeyStmt = db.prepare(`SELECT date(?, 'localtime') AS d`);

  const nonAtt = [];
  /** @type {Map<string, Array<Record<string, unknown>>>} */
  const attByDay = new Map();

  for (const r of rows) {
    if (r.type !== 'ATTACHMENT') {
      nonAtt.push(r);
      continue;
    }
    const dk = dayKeyStmt.get(r.created_at)?.d;
    const key = dk || String(r.created_at || '').slice(0, 10);
    if (!attByDay.has(key)) attByDay.set(key, []);
    attByDay.get(key).push(r);
  }

  /** @type {Array<{ row: Record<string, unknown>; attachments: Array<Record<string, unknown>> }>} */
  const mergedChunks = [];

  for (const [, group] of attByDay) {
    group.sort((a, b) =>
      String(a.created_at).localeCompare(String(b.created_at)),
    );
    const maxCreated = group.reduce((best, x) =>
      String(x.created_at) > String(best) ? x.created_at : best,
      group[0].created_at,
    );
    const descs = [
      ...new Set(
        group
          .map((g) => String(g.description || '').trim())
          .filter(Boolean),
      ),
    ];
    const mergedRow = {
      ...group[0],
      id: group[0].id,
      created_at: maxCreated,
      description: descs.join('\n\n'),
    };

    const allAtt = [];
    for (const ev of group) {
      const list = byEvent.get(ev.id);
      if (list) allAtt.push(...list);
    }
    allAtt.sort((a, b) =>
      String(a.created_at).localeCompare(String(b.created_at)),
    );

    mergedChunks.push({ row: mergedRow, attachments: allAtt });
  }

  mergedChunks.sort((a, b) =>
    String(b.row.created_at).localeCompare(String(a.row.created_at)),
  );

  nonAtt.sort((a, b) =>
    String(b.created_at).localeCompare(String(a.created_at)),
  );

  const out = [
    ...nonAtt,
    ...mergedChunks.map((c) => c.row),
  ];

  const mergedByEventId = new Map(
    mergedChunks.map((c) => [c.row.id, c.attachments]),
  );

  return out.map((r) =>
    r.type === 'ATTACHMENT'
      ? mapEvent(r, mergedByEventId.get(r.id) || [])
      : mapEvent(r, []),
  );
}
