import Link from 'next/link'
import { notFound } from 'next/navigation'
import { FolderTree, Plus, Map as MapIcon, MapPin, Camera } from 'lucide-react'
import { PageShell, PageHeader } from '@/components/page-shell'
import { BackButton } from '@/components/back-button'
import { db } from '@/lib/db'
import { searchItems } from '@/lib/search'
import { getMapChain } from '@/lib/maps'
import { ItemRow } from '@/components/item-row'
import { AddLocationDialog } from '../add-location-dialog'
import { LocationActions } from './location-actions'
import { NewMapDialog } from '../maps/new-map-dialog'
import { MapChain } from './map-chain'

export const dynamic = 'force-dynamic'

export default async function LocationDetailPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  const [location, children, allLocations, items, ownMaps, mapChain, pinnedOn] = await Promise.all([
    db.location.findUnique({ where: { id }, include: { parent: true } }),
    db.location.findMany({
      where: { parentId: id },
      orderBy: { name: 'asc' },
      select: { id: true, name: true, _count: { select: { items: true } } },
    }),
    db.location.findMany({
      orderBy: { path: 'asc' },
      select: { id: true, path: true },
    }),
    searchItems({ locationId: id, limit: 200 }),
    db.map.findMany({
      where: { locationId: id },
      orderBy: { createdAt: 'asc' },
      select: {
        id: true,
        name: true,
        imagePath: true,
        width: true,
        height: true,
        pins: { select: { id: true, x: true, y: true, locationId: true } },
      },
    }),
    getMapChain(id),
    db.locationPin.findMany({
      where: { locationId: id },
      include: { map: { select: { id: true, name: true } } },
    }),
  ])
  if (!location) notFound()

  // Maps that pin this location but aren't the immediate parent in the chain —
  // shown as a subtle "Also on …" hint so the user knows other views exist.
  const chainTailMapId = mapChain.length ? mapChain[mapChain.length - 1].map.id : null
  const otherMaps = pinnedOn
    .filter(p => p.mapId !== chainTailMapId)
    .map(p => ({ id: p.map.id, name: p.map.name }))

  // A child sublocation and its pin on one of this location's own maps are two
  // views of the same place. Map each child to the map(s) it's pinned on so the
  // list can show "on West Side" for placed children and flag the ones that
  // aren't on any map yet — they can never silently diverge again.
  const childMapNames = new Map<string, string[]>()
  for (const m of ownMaps) {
    for (const p of m.pins) {
      const arr = childMapNames.get(p.locationId)
      if (arr) arr.push(m.name)
      else childMapNames.set(p.locationId, [m.name])
    }
  }

  return (
    <PageShell>
      <div className="pt-2">
        <PageHeader
          title={location.name}
          back={<BackButton fallbackHref="/locations" />}
          action={
            <LocationActions
              id={location.id}
              name={location.name}
              parentId={location.parentId}
              locations={allLocations.filter(l => l.id !== id)}
            />
          }
        />

        <div className="text-sm text-muted-foreground mb-3">{location.path}</div>

        <MapChain
          chain={mapChain}
          currentLocationName={location.name}
          currentLocationId={location.id}
          otherMaps={otherMaps}
        />

        {ownMaps.length > 0 && (
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-2 mb-3">
            {ownMaps.map(m => (
              <Link
                key={m.id}
                href={`/locations/maps/${m.id}`}
                className="block rounded-xl border bg-card overflow-hidden hover:bg-accent/40"
              >
                <div
                  className="relative bg-muted"
                  style={{ aspectRatio: `${m.width} / ${m.height}` }}
                >
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={`/api/uploads/${m.imagePath}`}
                    alt={m.name}
                    className="absolute inset-0 w-full h-full object-contain"
                  />
                  {m.pins.map(p => (
                    <div
                      key={p.id}
                      style={{ left: `${p.x * 100}%`, top: `${p.y * 100}%` }}
                      className="absolute -translate-x-1/2 -translate-y-full pointer-events-none"
                    >
                      <MapPin className="size-4 fill-primary text-primary-foreground drop-shadow" />
                    </div>
                  ))}
                </div>
                <div className="p-3 flex items-center gap-2">
                  <MapIcon className="size-4 text-muted-foreground shrink-0" />
                  <div className="flex-1 min-w-0">
                    <div className="text-sm font-medium truncate">{m.name}</div>
                    <div className="text-xs text-muted-foreground">
                      {m.pins.length} pin{m.pins.length === 1 ? '' : 's'}
                    </div>
                  </div>
                </div>
              </Link>
            ))}
          </div>
        )}

        <NewMapDialog
          locations={[]}
          presetLocationId={location.id}
          presetLocationPath={location.path}
          trigger={
            <button className="w-full flex items-center justify-center gap-2 p-3 rounded-xl border-2 border-dashed text-sm text-muted-foreground hover:bg-accent/40 mb-3">
              <MapIcon className="size-4" />
              {ownMaps.length === 0
                ? `Add interior map for ${location.name}`
                : `Add another map for ${location.name}`}
            </button>
          }
        />

        <div className="space-y-2">
          {children.length > 0 && (
            <div className="rounded-xl border bg-card divide-y divide-border/60">
              {children.map(c => {
                const onMaps = childMapNames.get(c.id)
                return (
                  <Link
                    key={c.id}
                    href={`/locations/${c.id}`}
                    className="flex items-center gap-2 p-3 hover:bg-accent/40"
                  >
                    <FolderTree className="size-4 text-muted-foreground shrink-0" />
                    <span className="font-medium truncate">{c.name}</span>
                    {ownMaps.length > 0 &&
                      (onMaps ? (
                        <span className="inline-flex items-center gap-1 text-xs text-muted-foreground min-w-0">
                          <MapPin className="size-3 fill-primary text-primary-foreground shrink-0" />
                          <span className="truncate">{onMaps.join(', ')}</span>
                        </span>
                      ) : (
                        <span className="text-xs text-muted-foreground/50 shrink-0">
                          not on a map
                        </span>
                      ))}
                    <span className="ml-auto text-xs text-muted-foreground shrink-0">
                      {c._count.items}
                    </span>
                  </Link>
                )
              })}
            </div>
          )}

          <div className="flex items-center gap-2 pt-2">
            <AddLocationDialog
              locations={allLocations}
              defaultParentId={id}
              trigger={
                <button className="inline-flex items-center gap-1 h-9 px-3 rounded-lg border bg-card text-sm font-medium">
                  <Plus className="size-4" /> Sublocation
                </button>
              }
            />
          </div>
        </div>

        <div className="flex items-center justify-between mt-6 mb-2">
          <h2 className="text-sm font-medium uppercase tracking-wide text-muted-foreground">
            Items here ({items.length})
          </h2>
          <Link
            href={`/capture?at=${encodeURIComponent(location.path)}`}
            className="inline-flex items-center gap-1 h-9 px-3 rounded-lg bg-primary text-primary-foreground text-sm font-medium hover:bg-primary/90"
          >
            <Camera className="size-4" /> Capture here
          </Link>
        </div>
        <div className="space-y-2">
          {items.length === 0 ? (
            <Link
              href={`/capture?at=${encodeURIComponent(location.path)}`}
              className="block text-sm text-muted-foreground py-6 text-center rounded-xl border-2 border-dashed hover:bg-accent/40"
            >
              No items in this location yet. Tap to capture the first one.
            </Link>
          ) : (
            items.map(i => <ItemRow key={i.id} item={i} />)
          )}
        </div>
      </div>
    </PageShell>
  )
}
