import type { FastifyInstance } from "fastify";
import { z } from "zod";
import * as adsRepo from "../../repos/ads.js";
import * as pricingRepo from "../../repos/pricing.js";
import { writeAudit } from "../../audit/audit.js";

/** Rotas de anúncios + config de auto-pricing. Nível operador (autenticado). */

const idParams = z.object({ id: z.coerce.number().int().positive() });

const pricingConfigSchema = z.object({
  enabled: z.boolean().optional(),
  follow_strategy: z.enum(["beat_top", "match_rank"]).optional(),
  beat_amount: z.string().nullable().optional(),
  target_rank: z.number().int().positive().nullable().optional(),
  competitor_filter: z.unknown().optional(),
  min_profit_price: z.string().nullable().optional(),
  spot_guard_enabled: z.boolean().optional(),
  spot_symbol: z.string().nullable().optional(),
  spot_margin_ratio: z.string().nullable().optional(),
  min_price_step: z.string().nullable().optional(),
});

export async function adRoutes(app: FastifyInstance): Promise<void> {
  const auth = { preHandler: app.authenticate };

  app.get("/ads", auth, async (req) => {
    const q = z.object({ accountId: z.coerce.number().int().positive().optional() }).parse(req.query);
    return adsRepo.listAds(q.accountId);
  });

  app.get("/ads/:id", auth, async (req, reply) => {
    const { id } = idParams.parse(req.params);
    const ad = await adsRepo.getAdById(id);
    if (!ad) return reply.code(404).send({ error: "Anúncio não encontrado." });
    const config = await pricingRepo.getConfig(id);
    return { ...ad, pricing: config };
  });

  app.get("/ads/:id/pricing", auth, async (req, reply) => {
    const { id } = idParams.parse(req.params);
    const config = await pricingRepo.getConfig(id);
    if (!config) return reply.code(404).send({ error: "Sem config de pricing." });
    return config;
  });

  // Cria/atualiza a config de pricing do anúncio.
  app.put("/ads/:id/pricing", auth, async (req, reply) => {
    const { id } = idParams.parse(req.params);
    const ad = await adsRepo.getAdById(id);
    if (!ad) return reply.code(404).send({ error: "Anúncio não encontrado." });

    const parsed = pricingConfigSchema.safeParse(req.body);
    if (!parsed.success) {
      return reply.code(400).send({ error: "Dados inválidos.", issues: parsed.error.issues });
    }
    const d = parsed.data;
    await pricingRepo.upsertConfig(id, {
      enabled: d.enabled === undefined ? undefined : d.enabled ? 1 : 0,
      follow_strategy: d.follow_strategy,
      beat_amount: d.beat_amount,
      target_rank: d.target_rank,
      competitor_filter: d.competitor_filter,
      min_profit_price: d.min_profit_price,
      spot_guard_enabled: d.spot_guard_enabled === undefined ? undefined : d.spot_guard_enabled ? 1 : 0,
      spot_symbol: d.spot_symbol,
      spot_margin_ratio: d.spot_margin_ratio,
      min_price_step: d.min_price_step,
    });
    await writeAudit({
      userId: req.user.sub,
      action: "pricing.config",
      entity: "ad",
      entityId: id,
      detail: { fields: Object.keys(d) },
    });
    return pricingRepo.getConfig(id);
  });

  app.get("/ads/:id/adjustments", auth, async (req) => {
    const { id } = idParams.parse(req.params);
    return pricingRepo.listAdjustments(id, 100);
  });
}
