import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';

interface RibPrefixQuery {
  prefix?: string;
  router?: string;
}

interface RibDumpQuery {
  router?: string;
  asn?: string;
  limit?: string;
}

// risClient is injected from outside; lazy import avoids circular deps at startup
let risClient: any = null;

export function setRisClient(client: any): void {
  risClient = client;
}

export async function ribRoutes(fastify: FastifyInstance): Promise<void> {
  // GET /api/rib/prefix
  fastify.get<{ Querystring: RibPrefixQuery }>(
    '/rib/prefix',
    async (request: FastifyRequest<{ Querystring: RibPrefixQuery }>, reply: FastifyReply) => {
      reply.header('Access-Control-Allow-Origin', '*');
      reply.header('Cache-Control', 'no-store');

      if (!risClient) {
        return reply.status(503).send({ error: 'bio-rd RIS not configured' });
      }

      const prefix = request.query.prefix || '';
      const routerParam = request.query.router || 'default';

      if (!prefix) {
        return reply.status(400).send({ error: 'prefix required' });
      }

      try {
        const t0 = Date.now();
        const routers = await risClient.getRouters();
        const routerName = (routerParam === 'default' && routers.length > 0) ? routers[0] : routerParam;
        const [routes, longer] = await Promise.all([
          risClient.lpm(routerName, prefix),
          risClient.getLonger(routerName, prefix),
        ]);
        return reply.status(200).send({
          prefix,
          router: routerName,
          routes: routes || [],
          moreSpecifics: (longer || []).slice(0, 20),
          source: 'bio-rd-local',
          latencyMs: Date.now() - t0,
        });
      } catch (e: any) {
        return reply.status(500).send({ error: e.message });
      }
    }
  );

  // GET /api/rib/routers
  fastify.get(
    '/rib/routers',
    async (_request: FastifyRequest, reply: FastifyReply) => {
      reply.header('Access-Control-Allow-Origin', '*');
      reply.header('Cache-Control', 'no-store');

      if (!risClient) {
        return reply.status(503).send({ error: 'bio-rd RIS not configured' });
      }

      try {
        const routers = await risClient.getRouters();
        return reply.status(200).send({ routers: routers || [], source: 'bio-rd-local' });
      } catch (e: any) {
        return reply.status(500).send({ error: e.message });
      }
    }
  );

  // GET /api/rib/dump
  fastify.get<{ Querystring: RibDumpQuery }>(
    '/rib/dump',
    async (request: FastifyRequest<{ Querystring: RibDumpQuery }>, reply: FastifyReply) => {
      reply.header('Access-Control-Allow-Origin', '*');
      reply.header('Cache-Control', 'no-store');

      if (!risClient) {
        return reply.status(503).send({ error: 'bio-rd RIS not configured' });
      }

      const router = request.query.router || '';
      const asnFilter = request.query.asn ? parseInt(request.query.asn, 10) : undefined;
      const limit = Math.min(parseInt(request.query.limit || '100', 10), 1000);

      if (!router) {
        return reply.status(400).send({ error: 'router required' });
      }

      try {
        const t0 = Date.now();
        const allRoutes = await risClient.dumpRib(router, 'default', asnFilter);
        const routes = (allRoutes || []).slice(0, limit);
        return reply.status(200).send({
          router,
          routes,
          total: (allRoutes || []).length,
          source: 'bio-rd-local',
          latencyMs: Date.now() - t0,
        });
      } catch (e: any) {
        return reply.status(500).send({ error: e.message });
      }
    }
  );
}
