/**
 * Sales-triage urgency badges for interest list rows + cards.
 *
 * Derived purely from the dates we already return on the row, so this is a
 * pure function - no DB hits, no extra fetch. Mirrors the logic the
 * server-side alert-rules engine uses, but for at-a-glance rendering on
 * the list itself.
 */

const SILENT_DAYS_THRESHOLD = 7;
const EOI_AWAITING_DAYS_THRESHOLD = 14;
const DEPOSIT_PENDING_DAYS_THRESHOLD = 21;

// Mid-funnel = post-enquiry, pre-EOI. Surfaces the silent-deal warning so
// reps notice deals stuck in qualifying/nurturing without recent contact.
const ACTIVE_MID_FUNNEL_STAGES = new Set(['qualified', 'nurturing']);

export interface InterestUrgencyInput {
  pipelineStage: string;
  outcome?: string | null;
  archivedAt?: string | null;
  dateLastContact?: string | null;
  updatedAt?: string;
  dateEoiSent?: string | null;
  eoiStatus?: string | null;
  dateDepositReceived?: string | null;
}

export interface UrgencyBadge {
  /** Stable id for keying. */
  id: 'silent' | 'eoi_awaiting' | 'deposit_pending';
  label: string;
  /** Long form for tooltip / aria-label. */
  detail: string;
  /** Tailwind classes for the pill. */
  className: string;
}

function daysSince(iso: string | null | undefined): number | null {
  if (!iso) return null;
  const t = new Date(iso).getTime();
  if (Number.isNaN(t)) return null;
  return Math.floor((Date.now() - t) / 86_400_000);
}

export function computeUrgencyBadges(row: InterestUrgencyInput): UrgencyBadge[] {
  // Closed / archived interests don't need triage signals.
  if (row.archivedAt || row.outcome) return [];

  const badges: UrgencyBadge[] = [];

  // Silent in mid-funnel stages - most actionable.
  if (ACTIVE_MID_FUNNEL_STAGES.has(row.pipelineStage)) {
    const lastTouchIso = row.dateLastContact ?? row.updatedAt ?? null;
    const days = daysSince(lastTouchIso);
    if (days !== null && days >= SILENT_DAYS_THRESHOLD) {
      badges.push({
        id: 'silent',
        label: `Silent ${days}d`,
        detail: `No contact in ${days} days`,
        className: 'bg-amber-100 text-amber-800 border border-amber-200',
      });
    }
  }

  // EOI sent but not signed for too long.
  if (row.eoiStatus === 'waiting_for_signatures') {
    const days = daysSince(row.dateEoiSent);
    if (days !== null && days >= EOI_AWAITING_DAYS_THRESHOLD) {
      badges.push({
        id: 'eoi_awaiting',
        label: `EOI ${days}d`,
        detail: `EOI awaiting signature for ${days} days`,
        className: 'bg-orange-100 text-orange-800 border border-orange-200',
      });
    }
  }

  // EOI signed (or further along) but deposit not received yet. The deposit
  // is its own stage now; we trigger the warning while the deal is past EOI
  // signing but hasn't reached deposit_paid + has no dateDepositReceived.
  const eoiOrPast = row.pipelineStage === 'eoi' || row.pipelineStage === 'reservation';
  if (eoiOrPast && !row.dateDepositReceived && row.dateEoiSent) {
    const days = daysSince(row.dateEoiSent);
    if (days !== null && days >= DEPOSIT_PENDING_DAYS_THRESHOLD) {
      badges.push({
        id: 'deposit_pending',
        label: `Deposit ${days}d`,
        detail: `Awaiting deposit for ${days} days since EOI sent`,
        className: 'bg-rose-100 text-rose-800 border border-rose-200',
      });
    }
  }

  return badges;
}
