import { readFile } from 'fs/promises';
import { join } from 'path';

import type { MemberWorkSyncWatchdogCooldownPort } from '../../../core/application';

const DEFAULT_WATCHDOG_COOLDOWN_MS = 10 * 60_000;

interface StallJournalEntry {
  taskId: string;
  state: string;
  alertedAt?: string;
}

function parseTime(value: string | undefined): number | null {
  if (!value) {
    return null;
  }
  const time = new Date(value).getTime();
  return Number.isFinite(time) ? time : null;
}

export class TeamTaskStallJournalWorkSyncCooldown implements MemberWorkSyncWatchdogCooldownPort {
  constructor(
    private readonly teamsBasePath: string,
    private readonly cooldownMs: number = DEFAULT_WATCHDOG_COOLDOWN_MS
  ) {}

  async hasRecentNudge(input: {
    teamName: string;
    memberName: string;
    taskIds: string[];
    nowIso: string;
  }): Promise<boolean> {
    const taskIds = new Set(input.taskIds);
    if (taskIds.size === 0) {
      return false;
    }

    try {
      const raw = await readFile(
        join(this.teamsBasePath, input.teamName, 'stall-monitor-journal.json'),
        'utf8'
      );
      const parsed = JSON.parse(raw) as unknown;
      if (!Array.isArray(parsed)) {
        return true;
      }
      const now = parseTime(input.nowIso) ?? Date.now();
      return parsed.some((entry): boolean => {
        const row = entry as Partial<StallJournalEntry>;
        if (row.state !== 'alerted' || !row.taskId || !taskIds.has(row.taskId)) {
          return false;
        }
        const alertedAt = parseTime(row.alertedAt);
        return alertedAt != null && now - alertedAt <= this.cooldownMs;
      });
    } catch (error) {
      return (error as NodeJS.ErrnoException).code !== 'ENOENT';
    }
  }
}
