import type { Database } from "@/lib/supabase/database.types"

type PolicyRow = Database["public"]["Tables"]["resource_policies"]["Row"]
type PolicyRowWithOptionalActive = PolicyRow & { is_active?: boolean | null }

export const DEFAULT_CHECK_IN_WINDOW_MINUTES = 15

export function sanitizeCheckInWindowMinutes(
  value: number | null | undefined,
  fallback = DEFAULT_CHECK_IN_WINDOW_MINUTES,
) {
  if (typeof value !== "number" || !Number.isFinite(value)) {
    return fallback
  }

  const normalized = Math.trunc(value)
  if (normalized <= 0) {
    return fallback
  }

  return normalized
}

export function resolveCheckInWindowMinutes({
  resourceId,
  resourceTypeId,
  policies,
  fallback = DEFAULT_CHECK_IN_WINDOW_MINUTES,
}: {
  resourceId: string
  resourceTypeId: string | null
  policies: PolicyRow[]
  fallback?: number
}) {
  const activePolicies = policies.filter((policy) => {
    const policyWithOptionalActive = policy as PolicyRowWithOptionalActive
    return policyWithOptionalActive.is_active !== false
  })

  const policyForResource = activePolicies.find(
    (policy) => policy.resource_id === resourceId && policy.check_in_window_minutes !== null,
  )
  if (policyForResource) {
    return sanitizeCheckInWindowMinutes(policyForResource.check_in_window_minutes, fallback)
  }

  if (resourceTypeId) {
    const policyForType = activePolicies.find(
      (policy) => policy.resource_type_id === resourceTypeId && policy.check_in_window_minutes !== null,
    )
    if (policyForType) {
      return sanitizeCheckInWindowMinutes(policyForType.check_in_window_minutes, fallback)
    }
  }

  return fallback
}

export function isCheckInWindowOpen({
  startAt,
  endAt,
  now,
  windowMinutes,
}: {
  startAt: string
  endAt: string
  now: Date
  windowMinutes: number
}) {
  const nowMs = now.getTime()
  const startMs = new Date(startAt).getTime()
  const endMs = new Date(endAt).getTime()
  const windowStartMs = startMs - sanitizeCheckInWindowMinutes(windowMinutes) * 60 * 1000

  return nowMs >= windowStartMs && nowMs <= endMs
}

export function isNoShowDue({
  startAt,
  now,
  windowMinutes,
}: {
  startAt: string
  now: Date
  windowMinutes: number
}) {
  const nowMs = now.getTime()
  const startMs = new Date(startAt).getTime()
  const dueAtMs = startMs + sanitizeCheckInWindowMinutes(windowMinutes) * 60 * 1000

  return nowMs >= dueAtMs
}
