import { NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { db } from '@/lib/db'
import { visible } from '@/lib/scope'
import { triggerAgent } from '@/lib/agent-trigger'
import { logActivity } from '@/lib/activity'

export const runtime = 'nodejs'

type PinMeta = { shared: boolean; mine: boolean }
type ReminderPin = PinMeta & { pinId: string; kind: 'reminder'; id: string; title: string; done: boolean; topic: string | null; dueDate: Date | null; list: string | null; attachments: { id: string; name: string | null; image: boolean }[] }
type ItemPin = PinMeta & { pinId: string; kind: 'item'; id: string; title: string; done: boolean; topic: string | null; list: string | null; listId: string }
type ListPin = PinMeta & { pinId: string; kind: 'list'; id: string; name: string; items: { id: string; title: string; done: boolean; optional: boolean; topic: string | null }[] }

// GET /api/focus — the day's pinboard. Each pin references either a single
// reminder or a whole custom list (returned with its live items, expanded).
// Focus owns no state of its own; everything resolves to the canonical record.
export async function GET() {
  const session = await getSession()
  if (!session) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })

  const pins = await db.focusPin.findMany({
    where: visible.focusPin(session.userId),
    orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],
    include: {
      reminder: {
        include: { list: { select: { name: true } }, images: { select: { id: true, name: true, thumbPath: true } } },
      },
      checklist: {
        include: { items: { orderBy: { createdAt: 'asc' }, select: { id: true, title: true, done: true, optional: true, topic: true } } },
      },
      checklistItem: { include: { list: { select: { id: true, name: true } } } },
    },
  })

  return NextResponse.json({
    pins: pins.flatMap((p): (ReminderPin | ItemPin | ListPin)[] => {
      if (p.reminder) {
        const r = p.reminder
        return [{
          shared: p.scope === 'SHARED', mine: p.ownerId === session.userId,
          pinId: p.id, kind: 'reminder', id: r.id, title: r.title,
          done: r.completed, topic: r.topic, dueDate: r.dueDate, list: r.list?.name ?? null,
          attachments: r.images.map(a => ({ id: a.id, name: a.name, image: !!a.thumbPath })),
        }]
      }
      if (p.checklistItem) {
        const it = p.checklistItem
        return [{
          shared: p.scope === 'SHARED', mine: p.ownerId === session.userId,
          pinId: p.id, kind: 'item', id: it.id, title: it.title, done: it.done, topic: it.topic,
          list: it.list?.name ?? null, listId: it.listId,
        }]
      }
      if (p.checklist) {
        const c = p.checklist
        return [{
          shared: p.scope === 'SHARED', mine: p.ownerId === session.userId,
          pinId: p.id, kind: 'list', id: c.id, name: c.name,
          items: c.items.map(i => ({ id: i.id, title: i.title, done: i.done, optional: i.optional, topic: i.topic })),
        }]
      }
      return [] // orphaned pin (underlying record gone) — cascade should prevent this
    }),
  })
}

// POST /api/focus — pin something to Focus:
//   { reminderId }  pin an existing reminder      (idempotent)
//   { checklistId } pin a whole custom list       (idempotent)
//   { title }       create a reminder + pin it    (ad-hoc add — Focus owns nothing)
export async function POST(req: Request) {
  const session = await getSession()
  if (!session) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })

  const body = await req.json().catch(() => ({}))
  const wantShared = body.scope === 'SHARED'
  const pinScope = wantShared ? ('SHARED' as const) : ('PERSONAL' as const)
  const notShareable = () =>
    NextResponse.json({ error: 'only a household-visible item can be pinned to the shared board' }, { status: 400 })

  if (body.reminderId) {
    const reminder = await db.reminder.findFirst({ where: { id: body.reminderId, ...visible.reminder(session.userId) }, select: { id: true, title: true, visibility: true } })
    if (!reminder) return NextResponse.json({ error: 'reminder not found' }, { status: 404 })
    if (wantShared && reminder.visibility !== 'HOUSEHOLD') return notShareable()
    const pin = await db.focusPin.upsert({
      where: { ownerId_reminderId: { ownerId: session.userId, reminderId: reminder.id } },
      update: { scope: pinScope },
      create: { ownerId: session.userId, scope: pinScope, reminderId: reminder.id },
    })
    logActivity(session.userId, 'focus.pinned', `Pinned reminder to Focus: ${reminder.title}`)
    return NextResponse.json({ pinId: pin.id })
  }

  if (body.checklistItemId) {
    const item = await db.checklistItem.findFirst({ where: { id: body.checklistItemId, ...visible.checklistItem(session.userId) }, select: { id: true, title: true, list: { select: { visibility: true } } } })
    if (!item) return NextResponse.json({ error: 'item not found' }, { status: 404 })
    if (wantShared && item.list.visibility !== 'HOUSEHOLD') return notShareable()
    const pin = await db.focusPin.upsert({
      where: { ownerId_checklistItemId: { ownerId: session.userId, checklistItemId: item.id } },
      update: { scope: pinScope },
      create: { ownerId: session.userId, scope: pinScope, checklistItemId: item.id },
    })
    logActivity(session.userId, 'focus.pinned', `Pinned list item to Focus: ${item.title}`)
    return NextResponse.json({ pinId: pin.id })
  }

  if (body.checklistId) {
    const list = await db.checklist.findFirst({ where: { id: body.checklistId, ...visible.checklist(session.userId) }, select: { id: true, name: true, visibility: true } })
    if (!list) return NextResponse.json({ error: 'list not found' }, { status: 404 })
    if (wantShared && list.visibility !== 'HOUSEHOLD') return notShareable()
    const pin = await db.focusPin.upsert({
      where: { ownerId_checklistId: { ownerId: session.userId, checklistId: list.id } },
      update: { scope: pinScope },
      create: { ownerId: session.userId, scope: pinScope, checklistId: list.id },
    })
    logActivity(session.userId, 'focus.pinned', `Pinned list to Focus: ${list.name}`)
    return NextResponse.json({ pinId: pin.id })
  }

  // Ad-hoc add: create a real reminder (pushed to Apple) and pin it.
  const title = body.title?.trim()
  if (!title) return NextResponse.json({ error: 'title, reminderId, checklistId or checklistItemId required' }, { status: 400 })
  const reminder = await db.reminder.create({
    data: { ownerId: session.userId, title, syncState: 'PENDING_PUSH', pendingAction: 'create' },
    select: { id: true },
  })
  const pin = await db.focusPin.create({ data: { ownerId: session.userId, reminderId: reminder.id } })
  logActivity(session.userId, 'focus.added', `Added to Focus: ${title}`)
  triggerAgent('push').catch(() => {})
  return NextResponse.json({ pinId: pin.id, reminderId: reminder.id })
}

// DELETE /api/focus?done=1 — unpin items that are already done (completed
// reminders + checked-off list items); omit the flag to clear the whole board.
// Underlying records are untouched.
export async function DELETE(req: Request) {
  const session = await getSession()
  if (!session) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })

  const doneOnly = new URL(req.url).searchParams.get('done') === '1'
  const { count } = await db.focusPin.deleteMany({
    where: doneOnly
      ? { AND: [visible.focusPin(session.userId), { OR: [{ reminder: { completed: true } }, { checklistItem: { done: true } }] }] }
      : visible.focusPin(session.userId),
  })
  logActivity(session.userId, 'focus.cleared', `Unpinned ${count} ${doneOnly ? 'completed ' : ''}item${count === 1 ? '' : 's'} from Focus`)
  return NextResponse.json({ ok: true })
}
