import type { FastifyInstance } from 'fastify'
import type { Namespace } from '../types/webrtc.ts'
import { z } from 'zod'
import prisma from '../prisma/client.ts'
import { socketToClient } from '../utils/socket-to-client.ts'

export default function (fastify: FastifyInstance) {
  fastify.get('/preferences', async (req, reply) => {
    if (req.user) {
      return prisma.userPreferences.findFirst({ where: { userId: req.user.id } })
    }

    reply.code(401).send(false)
  })

  fastify.patch('/preferences', async (req, reply) => {
    if (!req.user) {
      reply.code(401).send(false)

      return
    }

    try {
      const schema = z.object({
        toggleInputHotkey: z.string().optional(),
        toggleOutputHotkey: z.string().optional(),
        volumes: z.record(z.string(), z.number()).optional(),
      })
      const input = schema.parse(req.body)

      return prisma.userPreferences.upsert({
        where: { userId: req.user.id },
        create: {
          userId: req.user.id,
          ...input,
        },
        update: input,
      })
    }
    catch (err) {
      fastify.log.error(err)
      reply.code(400)

      if (err instanceof z.ZodError) {
        reply.send({ error: z.prettifyError(err) })
      }
      else {
        reply.send({ error: err.message })
      }
    }
  })

  fastify.patch('/profile', async (req, reply) => {
    if (!req.user) {
      reply.code(401).send(false)

      return
    }

    try {
      const schema = z.object({
        displayName: z.string().optional(),
      })
      const input = schema.parse(req.body)

      const updatedUser = prisma.user.update({
        where: { id: req.user.id },
        data: {
          displayName: input.displayName,
        },
      })

      const namespace: Namespace = fastify.io.of('/webrtc')
      const sockets = await namespace.fetchSockets()

      const found = sockets.find(socket => socket.data.joined && socket.data.userId === req.user!.id)

      if (found) {
        found.data.displayName = input.displayName
        namespace.emit('clientChanged', found.id, socketToClient(found))
      }

      return updatedUser
    }
    catch (err) {
      fastify.log.error(err)
      reply.code(400)

      if (err instanceof z.ZodError) {
        reply.send({ error: z.prettifyError(err) })
      }
      else {
        reply.send({ error: err.message })
      }
    }
  })
}
