import 'server-only'
import { db } from '@/lib/db'
import type { PickerMap } from '@/components/location-map-picker'

export interface MapChainStep {
  map: {
    id: string
    name: string
    imagePath: string
    width: number
    height: number
  }
  pin: {
    x: number
    y: number
    /** Name of the location the pin points at (i.e., the next step toward `locationId`). */
    locationName: string
  }
}

/** All maps in the system with their pins, shaped for `LocationMapPicker`. */
export async function listMapsForPicker(): Promise<PickerMap[]> {
  const rows = await db.map.findMany({
    orderBy: [{ locationId: 'asc' }, { createdAt: 'asc' }],
    include: {
      location: { select: { path: true } },
      pins: {
        include: {
          location: { select: { id: true, name: true, path: true } },
        },
      },
    },
  })
  return rows.map(m => ({
    id: m.id,
    name: m.name,
    imagePath: m.imagePath,
    width: m.width,
    height: m.height,
    ownerLocationId: m.locationId,
    ownerPath: m.location?.path ?? null,
    pins: m.pins.map(p => ({
      id: p.id,
      x: p.x,
      y: p.y,
      locationId: p.location.id,
      locationName: p.location.name,
      locationPath: p.location.path,
    })),
  }))
}

function findPinForLocation(locId: string) {
  return db.locationPin.findFirst({
    where: { locationId: locId },
    orderBy: { createdAt: 'desc' },
    include: {
      map: {
        select: {
          id: true,
          name: true,
          imagePath: true,
          width: true,
          height: true,
          locationId: true,
        },
      },
      location: { select: { name: true } },
    },
  })
}

/**
 * Walks upward from `locationId` through any pins that reference it (or its
 * ancestors via map ownership), returning the chain of maps that lead to it.
 *
 * Result is ordered root-first → immediate-parent-last. Empty if the location
 * isn't pinned on any map. A cycle guard caps recursion at 10 levels.
 */
export async function getMapChain(locationId: string): Promise<MapChainStep[]> {
  const chain: MapChainStep[] = []
  let cursor: string | null = locationId
  const visited = new Set<string>()

  for (let i = 0; i < 10; i++) {
    if (!cursor) break
    if (visited.has(cursor)) break
    visited.add(cursor)

    const pin = await findPinForLocation(cursor)
    if (!pin) break

    chain.unshift({
      map: {
        id: pin.map.id,
        name: pin.map.name,
        imagePath: pin.map.imagePath,
        width: pin.map.width,
        height: pin.map.height,
      },
      pin: {
        x: pin.x,
        y: pin.y,
        locationName: pin.location.name,
      },
    })

    cursor = pin.map.locationId
  }

  return chain
}
