// Schemas de validação Zod para endpoints autenticados.
// Filosofia: permissivos no formato (não rejeitar requests do app legacy)
// mas estritos em tamanhos/limites (defesa contra payloads gigantes).
import { z } from 'zod';

// ===== /api/data (sync de estado completo) =====
// O cliente envia { data: {...estado todo do app...} }.
// db.setState recebe `data` e salva como JSON serializado.
// Permissivo: data tem que ser objeto, conteúdo livre.
// Tamanho do payload já é limitado por express.json({ limit: '10mb' }).
export const setStateSchema = z.object({
  data: z.record(z.string(), z.unknown()),
});

// ===== /api/share/:token/zones (atualizar zonas de geofencing do share) =====
// Cada zona: círculo geográfico (centro + raio) com tipo (proibida/atenção).
// Limite 100 zonas por share — suficiente pra qualquer caso real, bloqueia ataques de payload gigante.
export const zoneSchema = z.object({
  id: z.string().max(100).optional(),
  name: z.string().max(200).optional(),
  type: z.enum(['forbidden', 'warning']).optional(),
  center: z.object({
    lat: z.number().min(-90).max(90),
    lng: z.number().min(-180).max(180),
  }),
  radius: z.number().positive().max(100000), // metros, max 100km
});

export const updateZonesSchema = z.object({
  zones: z.array(zoneSchema).max(100),
});

// ===== Auth (signup + login) =====
export const signupSchema = z.object({
  email: z.string().email().max(200),
  password: z.string().min(8).max(100),
  name: z.string().max(100).optional(),
});

export const loginSchema = z.object({
  email: z.string().email().max(200),
  password: z.string().min(1).max(100),
});

// ===== Billing (checkout) =====
export const checkoutSchema = z.object({
  plan: z.enum(['pro', 'captain']),
  cycle: z.enum(['monthly', 'yearly']),
  billingType: z.enum(['PIX', 'CREDIT_CARD', 'BOLETO', 'UNDEFINED']).default('PIX'),
});

// ===== Middleware genérico =====
// Uso: app.post('/x', requireAuth, validate(mySchema), handler)
// Em caso de falha: 400 com até 5 issues do Zod (path + message).
// Em caso de sucesso: substitui req.body pelo resultado parseado (já tipado/coercido).
export function validate(schema) {
  return (req, res, next) => {
    const result = schema.safeParse(req.body);
    if (!result.success) {
      return res.status(400).json({
        error: 'Invalid payload',
        issues: result.error.issues.slice(0, 5).map(i => ({
          path: i.path.join('.'),
          message: i.message,
        })),
      });
    }
    req.body = result.data;
    next();
  };
}
