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

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

export type RuleUnit = "hours" | "days"

export const DEFAULT_BOOKING_ADVANCE_MINUTES = 10 * 24 * 60
export const DEFAULT_CANCELLATION_DEADLINE_MINUTES = 5 * 60
export const DEFAULT_EDITING_DEADLINE_MINUTES = DEFAULT_CANCELLATION_DEADLINE_MINUTES

export function minutesFromValueUnit(value: number, unit: RuleUnit) {
  const safe = Number.isFinite(value) ? Math.max(1, Math.trunc(value)) : 1
  return unit === "days" ? safe * 24 * 60 : safe * 60
}

export function valueUnitFromMinutes(
  minutes: number | null | undefined,
  fallback: { value: number; unit: RuleUnit },
) {
  if (typeof minutes !== "number" || !Number.isFinite(minutes) || minutes <= 0) {
    return fallback
  }

  if (minutes % (24 * 60) === 0) {
    return { value: Math.max(1, Math.trunc(minutes / (24 * 60))), unit: "days" as const }
  }

  return { value: Math.max(1, Math.trunc(Math.ceil(minutes / 60))), unit: "hours" as const }
}

export function toValidMinutes(value: number | null | undefined, fallback: number) {
  if (typeof value !== "number" || !Number.isFinite(value)) return fallback
  const normalized = Math.trunc(value)
  return normalized > 0 ? normalized : fallback
}

export function resolveReservationRules({
  resourceId,
  resourceTypeId,
  policies,
}: {
  resourceId: string
  resourceTypeId: string | null
  policies: PolicyRow[]
}) {
  const activePolicies = (policies as PolicyRowWithOptionalActive[]).filter(
    (policy) => policy.is_active !== false,
  )

  const policyForResource = activePolicies.find((policy) => policy.resource_id === resourceId)
  const policyForType =
    resourceTypeId === null
      ? undefined
      : activePolicies.find((policy) => policy.resource_type_id === resourceTypeId)
  const policy = policyForResource ?? policyForType
  const policyScope = policyForResource
    ? ("resource" as const)
    : policyForType
      ? ("resource_type" as const)
      : ("default" as const)

  const bookingAdvanceMinutes = toValidMinutes(
    policy?.booking_advance_minutes ??
      (typeof policy?.max_advance_days === "number" ? policy.max_advance_days * 24 * 60 : null),
    DEFAULT_BOOKING_ADVANCE_MINUTES,
  )

  const cancellationDeadlineMinutes = toValidMinutes(
    policy?.cancellation_deadline_minutes,
    DEFAULT_CANCELLATION_DEADLINE_MINUTES,
  )

  const editingDeadlineMinutes = toValidMinutes(
    policy?.editing_deadline_minutes,
    cancellationDeadlineMinutes || DEFAULT_EDITING_DEADLINE_MINUTES,
  )

  return {
    bookingAdvanceMinutes,
    cancellationDeadlineMinutes,
    editingDeadlineMinutes,
    policyScope,
  }
}

export function isAllowedUntilStart({
  now,
  startAt,
  minutesBeforeStart,
}: {
  now: Date
  startAt: string
  minutesBeforeStart: number
}) {
  const cutoff = new Date(new Date(startAt).getTime() - toValidMinutes(minutesBeforeStart, 1) * 60 * 1000)
  return now.getTime() <= cutoff.getTime()
}

export function getActionCutoff({
  startAt,
  minutesBeforeStart,
}: {
  startAt: string
  minutesBeforeStart: number
}) {
  return new Date(new Date(startAt).getTime() - toValidMinutes(minutesBeforeStart, 1) * 60 * 1000)
}
