/**
 * chatbot.routes.ts — CRUD de credenciais e bots IA por instância.
 *
 * Montado em /api/chatbot (ver server.ts)
 * Todos os endpoints requerem authMiddleware.
 */
import { Router, type Request, type Response } from 'express'
import { z } from 'zod'
import { prisma } from '../../infra/database/prisma'
import { credentialRepo, botRepo, chatBotState } from './chatbot.repository'
import { logger } from '../../config/logger'

export function buildChatbotRoutes(): Router {
  const router = Router()

  // ── Helpers ──────────────────────────────────────────────────────────────

  const validateInstance = async (instanceId: string, tenantId: string) => {
    return prisma.instance.findFirst({ where: { id: instanceId, tenantId } })
  }

  // ─────────────────────────────────────────────────────────────────────────
  // CREDENTIALS
  // ─────────────────────────────────────────────────────────────────────────

  // GET /api/chatbot/credentials/:instanceId
  router.get('/credentials/:instanceId', async (req: Request, res: Response) => {
    try {
      const tenantId = req.tenantId!
      const instanceId = req.params['instanceId'] as string
      if (!await validateInstance(instanceId, tenantId)) {
        res.status(404).json({ error: 'Instância não encontrada' }); return
      }
      const creds = await credentialRepo.findAll(tenantId, instanceId)
      res.json(creds)
    } catch (err: any) {
      logger.error({ err }, 'Erro ao listar credenciais')
      res.status(500).json({ error: err.message })
    }
  })

  // POST /api/chatbot/credentials/:instanceId
  router.post('/credentials/:instanceId', async (req: Request, res: Response) => {
    const schema = z.object({
      name: z.string().min(1).max(80),
      apiKey: z.string().min(10),
      provider: z.enum(['GEMINI', 'OPENAI']).default('GEMINI'),
    })
    try {
      const tenantId = req.tenantId!
      const instanceId = req.params['instanceId'] as string
      if (!await validateInstance(instanceId, tenantId)) {
        res.status(404).json({ error: 'Instância não encontrada' }); return
      }
      const body = schema.parse(req.body)
      const cred = await credentialRepo.create({ tenantId, instanceId, ...body } as any)
      res.status(201).json(cred)
    } catch (err: any) {
      if (err instanceof z.ZodError) { res.status(400).json({ error: err.errors }); return }
      logger.error({ err }, 'Erro ao criar credencial')
      res.status(500).json({ error: err.message })
    }
  })

  // DELETE /api/chatbot/credentials/:instanceId/:credId
  router.delete('/credentials/:instanceId/:credId', async (req: Request, res: Response) => {
    try {
      const tenantId = req.tenantId!
      const credId = req.params['credId'] as string
      await credentialRepo.delete(credId, tenantId)
      res.status(204).send()
    } catch (err: any) {
      logger.error({ err }, 'Erro ao deletar credencial')
      res.status(500).json({ error: err.message })
    }
  })

  // ─────────────────────────────────────────────────────────────────────────
  // BOTS
  // ─────────────────────────────────────────────────────────────────────────

  // GET /api/chatbot/bots/:instanceId
  router.get('/bots/:instanceId', async (req: Request, res: Response) => {
    try {
      const tenantId = req.tenantId!
      const instanceId = req.params['instanceId'] as string
      if (!await validateInstance(instanceId, tenantId)) {
        res.status(404).json({ error: 'Instância não encontrada' }); return
      }
      const bots = await botRepo.findAll(tenantId, instanceId)
      res.json(bots)
    } catch (err: any) {
      logger.error({ err }, 'Erro ao listar bots')
      res.status(500).json({ error: err.message })
    }
  })

  // POST /api/chatbot/bots/:instanceId
  router.post('/bots/:instanceId', async (req: Request, res: Response) => {
    const schema = z.object({
      credentialId: z.string().uuid(),
      name: z.string().min(1).max(80),
      systemPrompt: z.string().min(10),
      model: z.string().default('gemini-1.5-flash'),
      enabled: z.boolean().default(false),
      triggerMode: z.enum(['ALL', 'KEYWORD']).default('ALL'),
      keywords: z.array(z.string()).default([]),
    })
    try {
      const tenantId = req.tenantId!
      const instanceId = req.params['instanceId'] as string
      if (!await validateInstance(instanceId, tenantId)) {
        res.status(404).json({ error: 'Instância não encontrada' }); return
      }
      const body = schema.parse(req.body)
      const existing = await botRepo.findAll(tenantId, instanceId)
      if (existing.length > 0) {
        res.status(409).json({ error: 'Já existe um bot nesta instância. Use PUT para atualizar.' })
        return
      }
      const bot = await botRepo.create({ tenantId, instanceId, ...body } as any)
      res.status(201).json(bot)
    } catch (err: any) {
      if (err instanceof z.ZodError) { res.status(400).json({ error: err.errors }); return }
      logger.error({ err }, 'Erro ao criar bot')
      res.status(500).json({ error: err.message })
    }
  })

  // PUT /api/chatbot/bots/:instanceId/:botId
  router.put('/bots/:instanceId/:botId', async (req: Request, res: Response) => {
    const schema = z.object({
      credentialId: z.string().uuid().optional(),
      name: z.string().min(1).max(80).optional(),
      systemPrompt: z.string().min(10).optional(),
      model: z.string().optional(),
      enabled: z.boolean().optional(),
      triggerMode: z.enum(['ALL', 'KEYWORD']).optional(),
      keywords: z.array(z.string()).optional(),
    })
    try {
      const tenantId = req.tenantId!
      const botId = req.params['botId'] as string
      const body = schema.parse(req.body)
      await botRepo.update(botId, tenantId, body as any)
      const updated = await botRepo.findById(botId, tenantId)
      res.json(updated)
    } catch (err: any) {
      if (err instanceof z.ZodError) { res.status(400).json({ error: err.errors }); return }
      logger.error({ err }, 'Erro ao atualizar bot')
      res.status(500).json({ error: err.message })
    }
  })

  // DELETE /api/chatbot/bots/:instanceId/:botId
  router.delete('/bots/:instanceId/:botId', async (req: Request, res: Response) => {
    try {
      const tenantId = req.tenantId!
      const botId = req.params['botId'] as string
      await botRepo.delete(botId, tenantId)
      res.status(204).send()
    } catch (err: any) {
      logger.error({ err }, 'Erro ao deletar bot')
      res.status(500).json({ error: err.message })
    }
  })

  // ─────────────────────────────────────────────────────────────────────────
  // BOT STATE — Human Takeover por chat
  // ─────────────────────────────────────────────────────────────────────────

  // POST /api/chatbot/chats/:chatId/pause — pausa o bot (human takeover)
  router.post('/chats/:chatId/pause', async (req: Request, res: Response) => {
    try {
      await chatBotState.pauseBot(req.params['chatId'] as string)
      res.json({ paused: true })
    } catch (err: any) {
      res.status(500).json({ error: err.message })
    }
  })

  // POST /api/chatbot/chats/:chatId/resume — retoma o bot
  router.post('/chats/:chatId/resume', async (req: Request, res: Response) => {
    try {
      await chatBotState.resumeBot(req.params['chatId'] as string)
      res.json({ paused: false })
    } catch (err: any) {
      res.status(500).json({ error: err.message })
    }
  })

  return router
}
