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

export async function registerAdminUserRoutes(fastify) {
  fastify.get('/api/admin/users', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => {
    const qRaw = request.query?.q
    const q = typeof qRaw === 'string' ? qRaw.trim() : ''

    const pageRaw = request.query?.page
    const pageParsed = typeof pageRaw === 'string' ? Number(pageRaw) : Number(pageRaw)
    const page = Number.isFinite(pageParsed) && pageParsed > 0 ? Math.floor(pageParsed) : 1

    const pageSizeRaw = request.query?.pageSize
    const pageSizeParsed = typeof pageSizeRaw === 'string' ? Number(pageSizeRaw) : Number(pageSizeRaw)
    const pageSize = Number.isFinite(pageSizeParsed) && pageSizeParsed > 0 ? Math.floor(pageSizeParsed) : 20

    if (pageSize > 100) {
      reply.code(400).send({ error: 'pageSize должен быть ≤ 100' })
      return
    }

    const where = q
      ? {
          OR: [{ email: { contains: q } }, { displayName: { contains: q } }],
        }
      : undefined

    const total = await prisma.user.count({ where })

    const users = await prisma.user.findMany({
      where,
      select: {
        id: true,
        email: true,
        displayName: true,
        avatar: true,
        avatarStyle: true,
        createdAt: true,
        updatedAt: true,
      },
      orderBy: { updatedAt: 'desc' },
      skip: (page - 1) * pageSize,
      take: pageSize,
    })
    const items = users.map((u) => ({
      id: u.id,
      email: u.email,
      displayName: u.displayName,
      avatar: u.avatar,
      avatarStyle: u.avatarStyle,
      createdAt: u.createdAt,
      updatedAt: u.updatedAt,
    }))

    return { items, total, page, pageSize }
  })

  fastify.post('/api/admin/users', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => {
    const body = request.body ?? {}

    const email = normalizeEmail(body.email)
    if (!email || !email.includes('@')) {
      reply.code(400).send({ error: 'Некорректная почта' })
      return
    }

    const nameRaw = body.displayName
    const displayName = nameRaw === null || nameRaw === undefined ? null : String(nameRaw).trim()
    if (displayName !== null && displayName.length > 40) {
      reply.code(400).send({ error: 'Имя/ник максимум 40 символов' })
      return
    }

    const exists = await prisma.user.findUnique({ where: { email } })
    if (exists) {
      reply.code(409).send({ error: 'Почта уже занята' })
      return
    }

    const user = await prisma.user.create({
      data: {
        email,
        displayName: displayName && displayName.length ? displayName : null,
      },
    })

    reply.code(201).send({
      id: user.id,
      email: user.email,
      displayName: user.displayName,
      createdAt: user.createdAt,
      updatedAt: user.updatedAt,
    })
  })

  fastify.patch('/api/admin/users/:id', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => {
    const { id } = request.params
    const body = request.body ?? {}
    const adminUserId = request.user.sub

    const existing = await prisma.user.findUnique({ where: { id } })
    if (!existing) {
      reply.code(404).send({ error: 'Пользователь не найден' })
      return
    }

    const isSelf = id === adminUserId

    const data = {}

    if (body.email !== undefined) {
      if (isSelf) {
        reply.code(403).send({ error: 'Нельзя изменить свою почту через панель администратора' })
        return
      }
      const email = normalizeEmail(body.email)
      if (!email || !email.includes('@')) {
        reply.code(400).send({ error: 'Некорректная почта' })
        return
      }
      if (email !== existing.email) {
        const clash = await prisma.user.findUnique({ where: { email } })
        if (clash) {
          reply.code(409).send({ error: 'Почта уже занята' })
          return
        }
        data.email = email
      }
    }

    if (body.displayName !== undefined) {
      const nameRaw = body.displayName
      const name = nameRaw === null || nameRaw === undefined ? null : String(nameRaw).trim()
      if (name !== null && name.length > 40) {
        reply.code(400).send({ error: 'Имя/ник максимум 40 символов' })
        return
      }
      data.displayName = name && name.length ? name : null
    }

    const user = await prisma.user.update({ where: { id }, data })
    return {
      id: user.id,
      email: user.email,
      displayName: user.displayName,
      createdAt: user.createdAt,
      updatedAt: user.updatedAt,
    }
  })

  fastify.delete('/api/admin/users/:id', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => {
    const { id } = request.params
    const adminUserId = request.user.sub

    if (id === adminUserId) {
      reply.code(403).send({ error: 'Нельзя удалить свою учётную запись' })
      return
    }

    try {
      await prisma.user.delete({ where: { id } })
      reply.code(204).send()
    } catch (err) {
      request.log.error({ err }, '[admin-users] Operation failed')
      reply.code(404).send({ error: 'Пользователь не найден' })
    }
  })
}
