import { NextResponse } from "next/server"
import { createClient } from "@/lib/supabase/server"
import { isAdminUser } from "@/lib/auth/is-admin"
import { sendReservationReminderEmail } from "@/lib/notifications/reservation-reminder"
import { getActionCutoff, resolveReservationRules } from "@/lib/reservations/rules"
import { getResourceLocationPathLabel } from "@/lib/resources/location"

type SendReminderBody = {
  demo?: boolean
}

const DEFAULT_REMINDER_ADVANCE_MINUTES = 24 * 60

type ResourceTypeReminderConfig = {
  reminders_enabled?: boolean | null
  reminder_advance_minutes?: number | null
}

export async function POST(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  const { id } = await params
  const reservationId = id?.trim()
  if (!reservationId) {
    return NextResponse.json({ error: "El id de la reserva es obligatorio" }, { status: 400 })
  }

  const body = (await request.json().catch(() => ({}))) as SendReminderBody
  const isDemoTrigger = Boolean(body.demo)

  const supabase = await createClient()
  const {
    data: { user },
    error: userError,
  } = await supabase.auth.getUser()
  if (userError || !user) {
    return NextResponse.json({ error: "No autorizado" }, { status: 401 })
  }

  const { data: reservation, error: reservationError } = await (supabase.from("reservations") as any)
    .select("id, user_id, resource_id, start_at, end_at, status, reminder_sent_at")
    .eq("id", reservationId)
    .maybeSingle()

  if (reservationError) {
    return NextResponse.json({ error: "No se pudo consultar la reserva" }, { status: 500 })
  }
  if (!reservation) {
    return NextResponse.json({ error: "Reserva no encontrada" }, { status: 404 })
  }

  const canManage = reservation.user_id === user.id || isAdminUser(user)
  if (!canManage) {
    return NextResponse.json({ error: "No tienes permisos para enviar este recordatorio" }, { status: 403 })
  }

  if (reservation.status !== "confirmed") {
    return NextResponse.json({ error: "Solo se pueden enviar recordatorios de reservas confirmadas" }, { status: 409 })
  }

  if (reservation.reminder_sent_at && !isDemoTrigger) {
    return NextResponse.json({ error: "El recordatorio ya fue enviado" }, { status: 409 })
  }

  const { data: resource, error: resourceError } = await supabase
    .from("resources")
    .select("id, name, floor, metadata, resource_type_id")
    .eq("id", reservation.resource_id)
    .maybeSingle()

  if (resourceError) {
    return NextResponse.json({ error: "No se pudo consultar el recurso" }, { status: 500 })
  }
  if (!resource) {
    return NextResponse.json({ error: "Recurso no encontrado" }, { status: 404 })
  }

  const { data: resourceType, error: typeError } = await supabase
    .from("resource_types")
    .select("*")
    .eq("id", resource.resource_type_id)
    .maybeSingle()

  if (typeError) {
    return NextResponse.json({ error: "No se pudo consultar el tipo de recurso" }, { status: 500 })
  }
  if (!resourceType) {
    return NextResponse.json({ error: "Tipo de recurso no encontrado" }, { status: 404 })
  }

  const reminderConfig = resourceType as ResourceTypeReminderConfig
  if (reminderConfig.reminders_enabled !== true) {
    return NextResponse.json({ error: "El recordatorio está deshabilitado para este tipo de recurso" }, { status: 409 })
  }

  const { data: targetUser, error: targetUserError } = await supabase
    .from("users")
    .select("email, full_name")
    .eq("id", reservation.user_id)
    .maybeSingle()

  if (targetUserError) {
    return NextResponse.json({ error: "No se pudo consultar el usuario de la reserva" }, { status: 500 })
  }
  if (!targetUser?.email) {
    return NextResponse.json({ error: "El usuario de la reserva no tiene email" }, { status: 409 })
  }

  const { data: policies } = await supabase.from("resource_policies").select("*")
  const rules = resolveReservationRules({
    resourceId: resource.id,
    resourceTypeId: resource.resource_type_id,
    policies: policies ?? [],
  })

  const now = new Date()
  const advanceMinutes =
    typeof reminderConfig.reminder_advance_minutes === "number" && reminderConfig.reminder_advance_minutes > 0
      ? reminderConfig.reminder_advance_minutes
      : DEFAULT_REMINDER_ADVANCE_MINUTES
  const reminderAt = new Date(
    new Date(reservation.start_at).getTime() - advanceMinutes * 60 * 1000,
  )
  const cancellationCutoff = getActionCutoff({
    startAt: reservation.start_at,
    minutesBeforeStart: rules.cancellationDeadlineMinutes,
  })

  if (!isDemoTrigger && now.getTime() < reminderAt.getTime()) {
    return NextResponse.json(
      {
        error: "Aún no corresponde enviar el recordatorio",
        reminderAt: reminderAt.toISOString(),
      },
      { status: 409 },
    )
  }

  if (!isDemoTrigger && now.getTime() > cancellationCutoff.getTime()) {
    return NextResponse.json(
      {
        error: "La ventana para enviar recordatorio cerró porque ya venció el límite de cancelación",
        cancellationCutoff: cancellationCutoff.toISOString(),
      },
      { status: 409 },
    )
  }

  const locationLabel = [getResourceLocationPathLabel(resource), resource.floor].filter(Boolean).join(" • ")

  const emailResult = await sendReservationReminderEmail({
    to: targetUser.email,
    userName: targetUser.full_name ?? targetUser.email.split("@")[0] ?? "usuario",
    resourceName: resource.name,
    locationLabel: locationLabel || "Sin ubicación",
    startAt: reservation.start_at,
    endAt: reservation.end_at,
    cancellationDeadlineMinutes: rules.cancellationDeadlineMinutes,
  })

  if (!emailResult.ok) {
    return NextResponse.json(
      {
        error: "No se pudo enviar el email de recordatorio",
      },
      { status: 500 },
    )
  }

  await (supabase.from("reservations") as any)
    .update({ reminder_sent_at: new Date().toISOString() })
    .eq("id", reservation.id)

  return NextResponse.json({
    ok: true,
    sentTo: targetUser.email,
    providerId: emailResult.providerId ?? null,
    demo: isDemoTrigger,
  })
}
