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

const service = new AuthService()

// ─── Schemas de validação ─────────────────────────────────────────────────────

const registerSchema = z.object({
  name: z.string().min(2).max(100),
  email: z.string().email(),
  password: z.string().min(8).max(128),
  planId: z.string().uuid().optional(),
})

const loginSchema = z.object({
  email: z.string().email(),
  password: z.string().min(1),
})

const refreshSchema = z.object({
  refreshToken: z.string().min(1),
})

const changePasswordSchema = z.object({
  currentPassword: z.string().min(1),
  newPassword: z.string().min(8).max(128),
})

// ─── Helper para erros de validação / serviço ─────────────────────────────────

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' })
}

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

export const authRouter = Router()

/**
 * POST /api/auth/register
 * Cria novo tenant (usuário com role USER).
 * Retorna access + refresh token e dados do usuário.
 */
authRouter.post('/register', async (req: Request, res: Response) => {
  try {
    const body = registerSchema.parse(req.body) as any
    const result = await service.register(body)
    res.status(201).json(result)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * POST /api/auth/login
 * Autentica usuário. Retorna access + refresh token.
 */
authRouter.post('/login', async (req: Request, res: Response) => {
  try {
    const body = loginSchema.parse(req.body) as any
    const result = await service.login(body)
    res.json(result)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * POST /api/auth/refresh
 * Renova o access token usando o refresh token.
 */
authRouter.post('/refresh', async (req: Request, res: Response) => {
  try {
    const { refreshToken } = refreshSchema.parse(req.body)
    const result = await service.refresh(refreshToken)
    res.json(result)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * POST /api/auth/logout
 * Revoga o refresh token do usuário autenticado.
 */
authRouter.post('/logout', authMiddleware, async (req: Request, res: Response) => {
  try {
    await service.logout(req.tenantId!)
    res.json({ message: 'Sessão encerrada' })
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * GET /api/auth/me
 * Retorna dados do usuário autenticado + dias restantes do trial.
 */
authRouter.get('/me', authMiddleware, async (req: Request, res: Response) => {
  try {
    const user = await service.me(req.tenantId!)
    res.json(user)
  } catch (err) {
    handleError(res, err)
  }
})

/**
 * PATCH /api/auth/password
 * Altera a senha do usuário autenticado.
 */
authRouter.patch('/password', authMiddleware, async (req: Request, res: Response) => {
  try {
    const body = changePasswordSchema.parse(req.body) as any
    await service.changePassword(req.tenantId!, body)
    res.json({ message: 'Senha alterada com sucesso' })
  } catch (err) {
    handleError(res, err)
  }
})
