import { Driver } from '@core/racing/domain/entities/Driver';
import { League } from '@core/racing/domain/entities/League';
import { Race } from '@core/racing/domain/entities/Race';
import type { FeedItem } from '@core/social/domain/types/FeedItem';
import type { Friendship } from './RacingSeed';
import { seedId } from './SeedIdHelper';

export class RacingFeedFactory {
  constructor(
    private readonly baseDate: Date,
    private readonly persistence: 'postgres' | 'inmemory' = 'inmemory',
  ) {}

  create(drivers: Driver[], friendships: Friendship[], races: Race[], leagues: League[]): FeedItem[] {
    const items: FeedItem[] = [];
    const friendMap = new Map(friendships.map((f) => [`${f.driverId}:${f.friendId}`, true] as const));

    const completedRace = races.find((r) => r.status.toString() === 'completed');
    const upcomingRace = races.find((r) => r.status.toString() === 'scheduled');
    const league = leagues.find((l) => l.id.toString() === 'league-5') ?? leagues[0]!;

    const now = this.addMinutes(this.baseDate, 10);

    for (let i = 2; i <= 10; i++) {
      const actor = drivers.find((d) => d.id === seedId(`driver-${i}`, this.persistence));
      if (!actor) continue;

      if (!friendMap.has(`driver-1:${actor.id}`)) continue;

      items.push({
        id: seedId(`feed:${actor.id}:joined:${i}`, this.persistence),
        type: 'friend-joined-league',
        timestamp: this.addMinutes(now, -(i * 7)),
        actorDriverId: actor.id,
        actorFriendId: actor.id,
        leagueId: league.id.toString(),
        headline: `${actor.name} joined ${String(league.name)}`,
        body: 'Demo activity in in-memory mode.',
        ctaLabel: 'View league',
        ctaHref: `/leagues/${league.id.toString()}`,
      });

      if (completedRace) {
        items.push({
          id: seedId(`feed:${actor.id}:result:${i}`, this.persistence),
          type: 'friend-finished-race',
          timestamp: this.addMinutes(now, -(i * 7 + 3)),
          actorDriverId: actor.id,
          actorFriendId: actor.id,
          leagueId: completedRace.leagueId,
          raceId: completedRace.id,
          position: (i % 5) + 1,
          headline: `${actor.name} finished a race`,
          body: `Completed at ${completedRace.track}.`,
          ctaLabel: 'View results',
          ctaHref: `/races/${completedRace.id}/results`,
        });
      }
    }

    if (upcomingRace) {
      items.push({
        id: seedId(`feed:system:scheduled:${upcomingRace.id}`, this.persistence),
        type: 'new-race-scheduled',
        timestamp: this.addMinutes(now, -3),
        leagueId: upcomingRace.leagueId,
        raceId: upcomingRace.id,
        headline: `New race scheduled at ${upcomingRace.track}`,
        body: `${upcomingRace.car} • ${upcomingRace.scheduledAt.toISOString()}`,
        ctaLabel: 'View schedule',
        ctaHref: `/races/${upcomingRace.id}`,
      });
    }

    return items.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
  }

  private addMinutes(date: Date, minutes: number): Date {
    return new Date(date.getTime() + minutes * 60 * 1000);
  }
}