import { NextResponse } from "next/server"
import { createClient } from "@/lib/supabase/server"
import { isCheckInWindowOpen, resolveCheckInWindowMinutes } from "@/lib/reservations/policies"
import { isAdminUser } from "@/lib/auth/is-admin"

type CheckInBody = { reservationId?: string }

export async function POST(request: Request) {
  const body = (await request.json().catch(() => ({}))) as CheckInBody
  const reservationId = typeof body.reservationId === "string" ? body.reservationId.trim() : ""

  if (!reservationId) {
    return NextResponse.json({ error: "reservationId es obligatorio" }, { status: 400 })
  }

  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")
    .select("id, user_id, resource_id, start_at, end_at, status, checked_in_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 })
  }

  if (reservation.user_id !== user.id && !isAdminUser(user)) {
    return NextResponse.json({ error: "No tienes permisos para hacer check-in en esta reserva" }, { status: 403 })
  }

  if (reservation.status !== "confirmed") {
    return NextResponse.json({ error: "La reserva no está en estado confirmado" }, { status: 409 })
  }

  if (reservation.checked_in_at) {
    return NextResponse.json({ error: "La reserva ya tiene check-in realizado" }, { status: 409 })
  }

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

  if (resourceError) {
    return NextResponse.json({ error: "No se pudo consultar el recurso asociado a la reserva" }, { status: 500 })
  }

  if (!resource) {
    return NextResponse.json({ error: "No se encontró el recurso asociado a la reserva" }, { status: 404 })
  }

  const { data: policies, error: policyError } = await supabase
    .from("resource_policies")
    .select("*")

  if (policyError) {
    return NextResponse.json({ error: "No se pudieron consultar las políticas de check-in" }, { status: 500 })
  }

  const checkInWindowMinutes = resolveCheckInWindowMinutes({
    resourceId: reservation.resource_id,
    resourceTypeId: resource.resource_type_id,
    policies: policies ?? [],
  })

  const now = new Date()
  const canCheckIn = isCheckInWindowOpen({
    startAt: reservation.start_at,
    endAt: reservation.end_at,
    now,
    windowMinutes: checkInWindowMinutes,
  })

  if (!canCheckIn) {
    return NextResponse.json(
      {
        error: "La ventana de check-in está cerrada",
        checkInWindowMinutes,
      },
      { status: 409 },
    )
  }

  const { data: updatedReservation, error: updateError } = await supabase
    .from("reservations")
    .update({
      status: "checked_in",
      checked_in_at: now.toISOString(),
    })
    .eq("id", reservation.id)
    .eq("status", "confirmed")
    .select("id, status, checked_in_at")
    .maybeSingle()

  if (updateError) {
    return NextResponse.json({ error: "No se pudo registrar el check-in" }, { status: 500 })
  }

  if (!updatedReservation) {
    return NextResponse.json({ error: "No se pudo registrar el check-in" }, { status: 409 })
  }

  return NextResponse.json({
    ok: true,
    reservation: updatedReservation,
  })
}
