import type { Ticket } from "@/lib/schemas/ticket"

export type SlaTimerType = "response" | "solution"
export type SlaDisplayStatus = "on_track" | "at_risk" | "breached" | "met" | "n/a"

const DEFAULT_ALERT_THRESHOLD = 0.8

export function getSlaDueDate(ticket: Ticket, type: SlaTimerType): Date | null {
  if (type === "response") {
    return ticket.slaResponseDueAt ?? null
  }
  return ticket.slaSolutionDueAt ?? ticket.dueAt ?? null
}

export function getSlaDisplayStatus(ticket: Ticket, type: SlaTimerType, now: Date = new Date()): SlaDisplayStatus {
  const snapshot = ticket.slaSnapshot
  const dueAt = getSlaDueDate(ticket, type)
  const finalStatus = type === "response" ? ticket.slaResponseStatus : ticket.slaSolutionStatus

  if (!snapshot || !dueAt) {
    if (finalStatus === "met" || finalStatus === "breached") {
      return finalStatus
    }
    return "n/a"
  }

  if (finalStatus === "met" || finalStatus === "breached") {
    return finalStatus
  }

  const completedAt = type === "response" ? ticket.firstResponseAt : ticket.resolvedAt
  if (completedAt) {
    return completedAt.getTime() <= dueAt.getTime() ? "met" : "breached"
  }

  const elapsed = getEffectiveElapsedMs(ticket, now)
  const total = dueAt.getTime() - ticket.createdAt.getTime()
  if (total <= 0) {
    return now.getTime() <= dueAt.getTime() ? "on_track" : "breached"
  }

  if (now.getTime() > dueAt.getTime()) {
    return "breached"
  }

  const threshold = snapshot.alertThreshold ?? DEFAULT_ALERT_THRESHOLD
  const ratio = elapsed / total
  if (ratio >= 1) {
    return "breached"
  }
  if (ratio >= threshold) {
    return "at_risk"
  }
  return "on_track"
}

function getEffectiveElapsedMs(ticket: Ticket, now: Date) {
  const pausedMs = ticket.slaPausedMs ?? 0
  const pausedAt = ticket.slaPausedAt ?? null
  const createdAt = ticket.createdAt instanceof Date ? ticket.createdAt : new Date(ticket.createdAt)
  let elapsed = now.getTime() - createdAt.getTime() - pausedMs
  if (pausedAt) {
    elapsed -= now.getTime() - pausedAt.getTime()
  }
  return Math.max(0, elapsed)
}
