import { prisma } from '../../lib/prisma.js'

function validateBlockPayload(body, reply) {
  const key = String(body?.key || '').trim()
  const title = String(body?.title || '').trim()
  const content = String(body?.body || '').trim()
  const sort = Number(body?.sort ?? 0)
  const published = body?.published === undefined ? true : Boolean(body.published)

  if (!key) return reply.code(400).send({ error: 'key обязателен' })
  if (!/^[a-z0-9_-]{2,60}$/i.test(key)) {
    return reply.code(400).send({ error: 'key должен быть 2-60 символов: буквы, цифры, "_" или "-"' })
  }
  if (!title) return reply.code(400).send({ error: 'title обязателен' })
  if (title.length > 120) return reply.code(400).send({ error: 'title максимум 120 символов' })
  if (!content) return reply.code(400).send({ error: 'body обязателен' })
  if (content.length > 5000) return reply.code(400).send({ error: 'body максимум 5000 символов' })
  if (!Number.isFinite(sort) || Math.abs(sort) > 10_000) return reply.code(400).send({ error: 'Некорректный sort' })

  return { key, title, body: content, sort: Math.trunc(sort), published }
}

export async function registerInfoPageRoutes(fastify) {
  fastify.get('/api/info-page/blocks', async () => {
    const items = await prisma.infoPageBlock.findMany({
      where: { published: true },
      orderBy: [{ sort: 'asc' }, { createdAt: 'asc' }],
    })
    return { items }
  })

  fastify.get(
    '/api/admin/info-page/blocks',
    { preHandler: [fastify.verifyAdmin] },
    async () => {
      const items = await prisma.infoPageBlock.findMany({ orderBy: [{ sort: 'asc' }, { createdAt: 'asc' }] })
      return { items }
    },
  )

  fastify.post(
    '/api/admin/info-page/blocks',
    { preHandler: [fastify.verifyAdmin] },
    async (request, reply) => {
      const validated = validateBlockPayload(request.body, reply)
      if (!validated) return

      try {
        const item = await prisma.infoPageBlock.create({ data: validated })
        return reply.code(201).send({ item })
      } catch {
        return reply.code(409).send({ error: 'Блок с таким key уже существует' })
      }
    },
  )

  fastify.patch(
    '/api/admin/info-page/blocks/:id',
    { preHandler: [fastify.verifyAdmin] },
    async (request, reply) => {
      const { id } = request.params
      const existing = await prisma.infoPageBlock.findUnique({ where: { id } })
      if (!existing) return reply.code(404).send({ error: 'Блок не найден' })

      const body = request.body ?? {}
      const data = {}
      if (body.key !== undefined) {
        const key = String(body.key || '').trim()
        if (!key) return reply.code(400).send({ error: 'key обязателен' })
        if (!/^[a-z0-9_-]{2,60}$/i.test(key)) {
          return reply.code(400).send({ error: 'key должен быть 2-60 символов: буквы, цифры, "_" или "-"' })
        }
        data.key = key
      }
      if (body.title !== undefined) {
        const title = String(body.title || '').trim()
        if (!title) return reply.code(400).send({ error: 'title обязателен' })
        if (title.length > 120) return reply.code(400).send({ error: 'title максимум 120 символов' })
        data.title = title
      }
      if (body.body !== undefined) {
        const content = String(body.body || '').trim()
        if (!content) return reply.code(400).send({ error: 'body обязателен' })
        if (content.length > 5000) return reply.code(400).send({ error: 'body максимум 5000 символов' })
        data.body = content
      }
      if (body.sort !== undefined) {
        const sort = Number(body.sort)
        if (!Number.isFinite(sort) || Math.abs(sort) > 10_000) return reply.code(400).send({ error: 'Некорректный sort' })
        data.sort = Math.trunc(sort)
      }
      if (body.published !== undefined) {
        data.published = Boolean(body.published)
      }

      try {
        const item = await prisma.infoPageBlock.update({ where: { id }, data })
        return { item }
      } catch {
        return reply.code(409).send({ error: 'Блок с таким key уже существует' })
      }
    },
  )

  fastify.delete(
    '/api/admin/info-page/blocks/:id',
    { preHandler: [fastify.verifyAdmin] },
    async (request, reply) => {
      const { id } = request.params
      try {
        await prisma.infoPageBlock.delete({ where: { id } })
        return reply.code(204).send()
      } catch {
        return reply.code(404).send({ error: 'Блок не найден' })
      }
    },
  )
}
