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

// In-memory cache
let subCableCache: { ts: number; data: any } | null = null;
const CABLE_TTL = 24 * 60 * 60 * 1000;

async function fetchWithRetry(url: string, retries = 1, timeout = 30000): Promise<any> {
  for (let i = 0; i <= retries; i++) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeout);
    try {
      const response = await fetch(url, { signal: controller.signal });
      clearTimeout(timeoutId);
      if (!response.ok) {
        if (i === retries) throw new Error(`HTTP ${response.status}`);
        continue;
      }
      return await response.json();
    } catch (e) {
      clearTimeout(timeoutId);
      if (i === retries) throw e;
      await new Promise(r => setTimeout(r, 1500));
    }
  }
}

export async function submarineCablesRoutes(fastify: FastifyInstance): Promise<void> {
  fastify.get(
    '/submarine-cables',
    async (request: FastifyRequest, reply: FastifyReply) => {
      reply.header('Access-Control-Allow-Origin', '*');
      reply.header('Cache-Control', 'public, max-age=86400');

      if (subCableCache && Date.now() - subCableCache.ts < CABLE_TTL) {
        return reply.status(200).send(subCableCache.data);
      }

      try {
        const cableData = await fetchWithRetry("https://www.submarinecablemap.com/api/v3/cable/cable-geo.json", 1, 30000);
        
        if (cableData) {
          subCableCache = { ts: Date.now(), data: cableData };
          return reply.status(200).send(cableData);
        }
        
        return reply.status(503).send({ error: "Submarine cable data unavailable" });
      } catch (e: any) {
        return reply.status(500).send({ error: e.message });
      }
    }
  );
}
