export type TimelineItem = {
  itemId: string;
  occurredAt: string;
  eventName: string;
  productId: string;
  title: string;
  summary?: string | null;
  artifactRefs: string[];
  relatedEventIds: string[];
  actorType: 'user' | 'agent' | 'system' | 'device';
  visibility: 'private' | 'org' | 'shared' | 'local-only';
  correlationId?: string | null;
};

export type TimelineGroup = {
  groupId: string;
  correlationId: string | null;
  items: TimelineItem[];
  productIds: string[];
  latestOccurredAt: string;
};

export const TIMELINE_PRODUCT_OPTIONS = [
  { value: 'current', label: 'Current Admin Product' },
  { value: 'lysnrai', label: 'LysnrAI' },
  { value: 'notelett', label: 'NoteLett' },
  { value: 'mindlyst', label: 'MindLyst' },
  { value: 'flowmonk', label: 'FlowMonk' },
  { value: 'chronomind', label: 'ChronoMind' },
  { value: 'efforise', label: 'EffoRise' },
  { value: 'actiontrail', label: 'ActionTrail' },
  { value: 'cowork', label: 'Cowork' },
] as const;

function compareDescendingIso(a: string, b: string) {
  return new Date(b).getTime() - new Date(a).getTime();
}

export function getTimelineStats(items: TimelineItem[]) {
  return {
    uniqueProducts: new Set(items.map(item => item.productId)).size,
    uniqueCorrelations: new Set(
      items
        .map(item => item.correlationId)
        .filter((value): value is string => typeof value === 'string' && value.length > 0)
    ).size,
    withArtifacts: items.filter(item => item.artifactRefs.length > 0).length,
    groupedChains: buildTimelineGroups(items).filter(group => group.items.length > 1).length,
  };
}

export function buildTimelineGroups(items: TimelineItem[]): TimelineGroup[] {
  const groups = new Map<string, TimelineItem[]>();

  for (const item of items) {
    const groupKey = item.correlationId?.trim()
      ? `corr:${item.correlationId}`
      : `item:${item.itemId}`;
    const bucket = groups.get(groupKey);
    if (bucket) {
      bucket.push(item);
    } else {
      groups.set(groupKey, [item]);
    }
  }

  return [...groups.entries()]
    .map(([groupId, groupItems]) => {
      const itemsSorted = [...groupItems].sort((left, right) =>
        compareDescendingIso(left.occurredAt, right.occurredAt)
      );
      return {
        groupId,
        correlationId: itemsSorted[0]?.correlationId?.trim() || null,
        items: itemsSorted,
        productIds: [...new Set(itemsSorted.map(item => item.productId))],
        latestOccurredAt: itemsSorted[0]?.occurredAt ?? new Date(0).toISOString(),
      };
    })
    .sort((left, right) => compareDescendingIso(left.latestOccurredAt, right.latestOccurredAt));
}

export function getProductLabel(productId: string) {
  return TIMELINE_PRODUCT_OPTIONS.find(option => option.value === productId)?.label ?? productId;
}
