import { authenticateApiRequest } from '@/lib/api-auth'
import { prisma } from '@/lib/prisma'
import { productAccessFilter } from '@/lib/product-access'
import { Prisma } from '@prisma/client'
import { z } from 'zod'
import { enforceUserRateLimit } from '@/lib/rate-limit'

const metadataField = z.record(z.string(), z.unknown()).optional()

const logSchema = z.discriminatedUnion('type', [
  z.object({
    type: z.literal('IMPLEMENTATION_PLAN'),
    content: z.string().min(1),
    metadata: metadataField,
  }),
  z.object({
    type: z.literal('TEST_RESULT'),
    content: z.string().min(1),
    status: z.enum(['PASSED', 'FAILED']),
    metadata: metadataField,
  }),
  z.object({
    type: z.literal('COMMIT'),
    content: z.string().min(1),
    commit_hash: z.string().min(1),
    commit_message: z.string().min(1),
    metadata: metadataField,
  }),
])

export async function POST(
  request: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  const auth = await authenticateApiRequest(request)
  if ('error' in auth) {
    return Response.json({ error: auth.error }, { status: auth.status })
  }
  if (auth.isDemo) {
    return Response.json({ error: 'Niet beschikbaar in demo-modus' }, { status: 403 })
  }

  const limited = enforceUserRateLimit('log-story', auth.userId)
  if (limited) return Response.json({ error: limited.error }, { status: 429 })

  const { id: storyId } = await params

  const story = await prisma.story.findFirst({
    where: { id: storyId, product: productAccessFilter(auth.userId) },
  })
  if (!story) {
    return Response.json({ error: 'Story niet gevonden' }, { status: 404 })
  }

  let body: unknown
  try {
    body = await request.json()
  } catch {
    return Response.json({ error: 'Malformed JSON' }, { status: 400 })
  }
  const parsed = logSchema.safeParse(body)
  if (!parsed.success) {
    return Response.json({ error: parsed.error.flatten() }, { status: 422 })
  }

  const log = await prisma.storyLog.create({
    data: {
      story_id: storyId,
      type: parsed.data.type,
      content: parsed.data.content,
      status: 'status' in parsed.data ? parsed.data.status : null,
      commit_hash: 'commit_hash' in parsed.data ? parsed.data.commit_hash : null,
      commit_message: 'commit_message' in parsed.data ? parsed.data.commit_message : null,
      metadata: parsed.data.metadata
        ? (parsed.data.metadata as Prisma.InputJsonValue)
        : Prisma.JsonNull,
    },
  })

  return Response.json({ id: log.id, created_at: log.created_at }, { status: 201 })
}
