/*
 * Batch identification helper for IDENTIFY_MODE=queue.
 *
 * Usage:
 *   npm run identify                 # list all pending jobs with image URLs
 *   npm run identify -- --apply <jobId> --name "..." --category "..." --tags "a,b,c"
 *
 * Designed to be piloted by a human or by Claude Code on the server, so we
 * don't spend Anthropic API tokens on auto-identification.
 */
import { PrismaClient } from '@prisma/client'

const db = new PrismaClient()

function arg(name: string): string | undefined {
  const i = process.argv.indexOf(`--${name}`)
  if (i === -1) return undefined
  return process.argv[i + 1]
}

async function listPending() {
  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || ''
  const jobs = await db.identificationJob.findMany({
    where: { status: 'PENDING' },
    orderBy: { createdAt: 'asc' },
    include: {
      photo: {
        include: {
          item: {
            include: {
              location: true,
              photos: { orderBy: [{ isPrimary: 'desc' }, { createdAt: 'asc' }] },
            },
          },
        },
      },
    },
  })
  if (jobs.length === 0) {
    console.log('No pending identification jobs.')
    return
  }
  console.log(`${jobs.length} pending job(s):\n`)
  for (const j of jobs) {
    console.log(`Job ${j.id}`)
    console.log(`  Item: ${j.photo.item.name} (${j.photo.item.id})`)
    console.log(`  Location: ${j.photo.item.location.path}`)
    console.log(`  Photos (${j.photo.item.photos.length}):`)
    for (const p of j.photo.item.photos) {
      const tag = p.isPrimary ? ' [primary]' : ''
      console.log(`    - ${baseUrl}/api/uploads/${p.path}${tag}`)
      console.log(`      thumb: ${baseUrl}/api/uploads/${p.thumbPath}`)
    }
    console.log(
      `  Apply: npm run identify -- --apply ${j.id} --name "..." --category "..." --tags "a,b,c"`,
    )
    console.log('')
  }
}

async function apply(jobId: string) {
  const job = await db.identificationJob.findUnique({
    where: { id: jobId },
    include: { photo: true },
  })
  if (!job) {
    console.error(`Job ${jobId} not found`)
    process.exit(1)
  }
  const name = arg('name')
  const category = arg('category') || null
  const brand = arg('brand') || null
  const tagsRaw = arg('tags') || ''
  const tags = tagsRaw
    .split(',')
    .map(s => s.trim().toLowerCase())
    .filter(Boolean)

  if (!name) {
    console.error('--name is required')
    process.exit(1)
  }

  await db.$transaction(async tx => {
    await tx.item.update({
      where: { id: job.photo.itemId },
      data: {
        name,
        category,
        brand,
        tags: {
          connectOrCreate: tags.map(n => ({
            where: { name: n },
            create: { name: n },
          })),
        },
      },
    })
    await tx.identificationJob.update({
      where: { id: jobId },
      data: { status: 'DONE', processedAt: new Date() },
    })
    // Rebuild searchText
    const it = await tx.item.findUnique({
      where: { id: job.photo.itemId },
      include: { tags: true, location: true },
    })
    if (it) {
      const parts = [
        it.name, it.description, it.category, it.brand,
        it.serialNumber, it.notes, it.location.path,
        it.tags.map(t => t.name).join(' '),
      ].filter(Boolean)
      await tx.item.update({
        where: { id: it.id },
        data: { searchText: parts.join(' ').toLowerCase() },
      })
    }
  })

  console.log(`Applied: ${name} (${tags.join(', ') || 'no tags'})`)
}

async function main() {
  const applyId = arg('apply')
  if (applyId) {
    await apply(applyId)
  } else {
    await listPending()
  }
}

main()
  .catch(err => {
    console.error(err)
    process.exit(1)
  })
  .finally(() => db.$disconnect())
