import type { FastifyInstance } from "fastify";
import { z } from "zod";
import * as ordersRepo from "../../repos/orders.js";
import * as chatRepo from "../../repos/chat.js";
import { exchangeClientForAccount } from "../../exchange/index.js";
import { writeAudit } from "../../audit/audit.js";

/** Rotas de ordens + chat. Nível operador (autenticado). */

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

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

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

  app.get("/orders/:id", auth, async (req, reply) => {
    const { id } = idParams.parse(req.params);
    const order = await ordersRepo.getById(id);
    if (!order) return reply.code(404).send({ error: "Ordem não encontrada." });
    const messages = await chatRepo.listByOrder(order.order_no);
    return { ...order, messages };
  });

  // Envio manual de mensagem pelo operador (chat da exchange).
  app.post("/orders/:id/chat", auth, async (req, reply) => {
    const { id } = idParams.parse(req.params);
    const body = z.object({ text: z.string().min(1) }).safeParse(req.body);
    if (!body.success) return reply.code(400).send({ error: "Texto obrigatório." });

    const order = await ordersRepo.getById(id);
    if (!order) return reply.code(404).send({ error: "Ordem não encontrada." });

    try {
      const client = await exchangeClientForAccount(order.account_id);
      await client.sendChatMessage(order.order_no, body.data.text);
      await chatRepo.insertOutgoing(order.order_no, order.id, body.data.text, false);
      await writeAudit({
        userId: req.user.sub,
        action: "chat.manual_send",
        entity: "order",
        entityId: order.id,
        detail: { orderNo: order.order_no },
      });
      return { ok: true };
    } catch (err) {
      return reply.code(502).send({ ok: false, error: err instanceof Error ? err.message : String(err) });
    }
  });
}
