import {
  jobsMatchEmployerAndTitleDismiss,
  PRIOR_SKIP_DISMISS_LOOKBACK_MS,
} from "@shared/job-fingerprint";
import type { JobListItem, JobStatus } from "@shared/types";

export type DuplicateDismissReason = "skipped" | "applied";

const OPEN_JOB_STATUSES = new Set<JobStatus>([
  "discovered",
  "ready",
  "processing",
]);

function isWithinDismissLookback(updatedAt: string, nowMs: number): boolean {
  const updatedMs = Date.parse(updatedAt);
  if (!Number.isFinite(updatedMs)) return false;
  return nowMs - updatedMs <= PRIOR_SKIP_DISMISS_LOOKBACK_MS;
}

/**
 * Map open jobs to a prior skip/apply when the same company and title match
 * within the last 90 days (see {@link PRIOR_SKIP_DISMISS_LOOKBACK_MS}).
 */
export function buildDuplicateDismissHints(
  jobs: readonly JobListItem[],
  nowMs: number = Date.now(),
): Map<string, DuplicateDismissReason> {
  const dismissed: Array<{
    employer: string;
    title: string;
    reason: DuplicateDismissReason;
  }> = [];

  for (const job of jobs) {
    if (job.status !== "skipped" && job.status !== "applied") continue;
    if (!isWithinDismissLookback(job.updatedAt, nowMs)) continue;
    dismissed.push({
      employer: job.employer,
      title: job.title,
      reason: job.status === "applied" ? "applied" : "skipped",
    });
  }

  const hints = new Map<string, DuplicateDismissReason>();
  for (const job of jobs) {
    if (!OPEN_JOB_STATUSES.has(job.status)) continue;
    for (const prior of dismissed) {
      if (
        jobsMatchEmployerAndTitleDismiss({
          employerA: job.employer,
          titleA: job.title,
          employerB: prior.employer,
          titleB: prior.title,
        })
      ) {
        hints.set(job.id, prior.reason);
        break;
      }
    }
  }

  return hints;
}
