import { Router, type Request, type Response } from "express";
import { nanoid } from "nanoid";
import type { Flow } from "../types/flow.js";
import {
  type DB,
  createSession,
  getSession,
  appendMessage,
  logEvent,
} from "../database.js";
import { advance, resolveAnswer, handleAiTurn } from "../flow-engine.js";

export function sessionRoutes(flow: Flow, db: DB): Router {
  const router = Router();

  // ─── POST /api/session/start ────────────────────────────
  router.post("/start", async (req: Request, res: Response) => {
    try {
      const sessionId = nanoid(16);
      const { visitor_id, utm, user_agent } = req.body ?? {};

      createSession(db, {
        id: sessionId,
        visitor_id,
        start_block_id: flow.start_block_id,
        utm,
        user_agent: user_agent ?? req.headers["user-agent"],
      });
      logEvent(db, sessionId, "session_started", flow.start_block_id);

      const step = await advance(flow, db, sessionId, flow.start_block_id);
      res.json({ session_id: sessionId, step });
    } catch (err) {
      res.status(500).json({
        error: "start_failed",
        message: (err as Error).message,
      });
    }
  });

  // ─── POST /api/session/:id/answer ───────────────────────
  router.post("/:id/answer", async (req: Request, res: Response) => {
    try {
      const sessionId = req.params.id;
      const session = getSession(db, sessionId);
      if (!session) {
        return res.status(404).json({ error: "session_not_found" });
      }
      if (session.status !== "active") {
        return res.status(409).json({ error: "session_not_active" });
      }

      const { block_id, answer } = req.body ?? {};
      if (!block_id) {
        return res.status(400).json({ error: "block_id_required" });
      }

      const nextBlockId = resolveAnswer(flow, db, sessionId, block_id, answer ?? {});
      const step = await advance(flow, db, sessionId, nextBlockId);
      return res.json({ step });
    } catch (err) {
      return res.status(500).json({
        error: "answer_failed",
        message: (err as Error).message,
      });
    }
  });

  // ─── POST /api/session/:id/ai-turn ──────────────────────
  router.post("/:id/ai-turn", async (req: Request, res: Response) => {
    try {
      const sessionId = req.params.id;
      const session = getSession(db, sessionId);
      if (!session) {
        return res.status(404).json({ error: "session_not_found" });
      }
      if (session.status !== "active") {
        return res.status(409).json({ error: "session_not_active" });
      }

      const { block_id, message } = req.body ?? {};
      if (!block_id || !message) {
        return res.status(400).json({ error: "block_id_and_message_required" });
      }

      const result = await handleAiTurn(flow, db, sessionId, block_id, message);

      if (result.nextBlockId) {
        const step = await advance(flow, db, sessionId, result.nextBlockId);
        return res.json({
          reply: result.reply,
          intent: result.intent,
          step,
        });
      }

      return res.json({ reply: result.reply, intent: result.intent });
    } catch (err) {
      return res.status(500).json({
        error: "ai_turn_failed",
        message: (err as Error).message,
      });
    }
  });

  // ─── GET /api/session/:id ───────────────────────────────
  router.get("/:id", (req: Request, res: Response) => {
    const session = getSession(db, req.params.id);
    if (!session) return res.status(404).json({ error: "session_not_found" });
    return res.json(session);
  });

  return router;
}
