import { Router, type Request, type Response } from 'express'
import { z } from 'zod'
import { PairService } from './pair.service'
import { authMiddleware } from '../../shared/middlewares/auth.middleware'

const service = new PairService()

function handleError(res: Response, err: unknown) {
  if (err instanceof z.ZodError) {
    res.status(400).json({ error: 'Dados inválidos', details: err.flatten().fieldErrors })
    return
  }
  const e = err as Error & { statusCode?: number }
  res.status(e.statusCode ?? 500).json({ error: e.message ?? 'Erro interno' })
}

// ─── Schemas ──────────────────────────────────────────────────────────────────

const requestSchema = z.object({
  email:        z.string().email(),
  clientSystem: z.string().min(1).max(100),
  clientName:   z.string().min(1).max(200),
  clientUrl:    z.string().url().nullable().optional(),
})

const confirmSchema = z.object({
  email:        z.string().email(),
  code:         z.string().length(6),
  clientSystem: z.string().min(1).max(100),
  clientName:   z.string().min(1).max(200),
  clientUrl:    z.string().url().nullable().optional(),
})

// ─── Router ───────────────────────────────────────────────────────────────────

export const pairRouter = Router()

/**
 * POST /api/pair/request
 * Inicia pareamento: gera OTP e envia por e-mail.
 * Público (chamado pelo sistema cliente).
 */
pairRouter.post('/request', async (req: Request, res: Response) => {
  try {
    const body = requestSchema.parse(req.body) as any
    const result = await service.request({
      ...body,
      clientUrl: body.clientUrl ?? null,
    })
    res.json(result)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * POST /api/pair/confirm
 * Confirma o OTP e retorna a integration_key.
 * Público (chamado pelo sistema cliente com o código que o usuário digitou).
 */
pairRouter.post('/confirm', async (req: Request, res: Response) => {
  try {
    const body = confirmSchema.parse(req.body) as any
    const result = await service.confirm({
      ...body,
      clientUrl: body.clientUrl ?? null,
    })
    res.json(result)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * GET /api/pair/verify
 * Verifica se uma integration_key é válida.
 * Público — autenticado pelo header x-nw-key.
 */
pairRouter.get('/verify', async (req: Request, res: Response) => {
  try {
    const raw = req.headers['x-nw-key']
    const key = Array.isArray(raw) ? raw[0] : raw
    if (!key) {
      res.status(401).json({ error: 'Header x-nw-key ausente' })
      return
    }
    const result = await service.verify(key)
    res.json(result)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * GET /api/pair/connections
 * Lista pares ativos do usuário autenticado.
 * Protegido — requer JWT via authMiddleware.
 */
pairRouter.get('/connections', authMiddleware, async (req: Request, res: Response) => {
  try {
    const pairs = await service.list(req.tenantId!)
    res.json(pairs)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * DELETE /api/pair/connections/:id
 * Revoga um par do usuário autenticado.
 * Protegido — requer JWT via authMiddleware.
 */
pairRouter.delete('/connections/:id', authMiddleware, async (req: Request, res: Response) => {
  try {
    const result = await service.revoke(req.tenantId!, String(req.params.id))
    res.json(result)
  } catch (err) {
    handleError(res, err)
  }
})
