'use strict';

const express = require('express');
const rateLimit = require('express-rate-limit');
const { ProxyRegistry } = require('../proxy/registry');
const { proxyKey } = require('../proxy/registry');

function buildProxyRoutes(opts) {
  const { cfg, state, proxyRegistry, logger, validateProxyUpload, rateLimits } = opts;
  const router = express.Router();

  const uploadLimiter = rateLimit({
    windowMs: 60 * 60 * 1000,
    max: rateLimits?.proxy_upload_per_hour || 10,
    standardHeaders: true,
    legacyHeaders: false,
    handler: (req, res) => res.status(429).json({ error: 'Too many proxy uploads. Try again later.' }),
  });

  router.post('/upload', uploadLimiter, (req, res) => {
    const text = req.body?.proxies;
    const validation = validateProxyUpload(text);
    if (!validation.ok) return res.status(400).json({ error: validation.error });
    const result = proxyRegistry.validateNew(text, { target: state.currentTarget });
    res.json({
      success: true,
      jobId: result.jobId,
      queued: result.queued,
      duplicates: result.duplicates,
      invalid: result.invalid,
      total: result.total,
    });
  });

  router.get('/list', (req, res) => {
    const status = req.query.status;
    const sortBy = req.query.sortBy;
    const limit = parseInt(req.query.limit, 10) || 0;
    const offset = parseInt(req.query.offset, 10) || 0;
    const proxies = proxyRegistry.list({ status, sortBy, limit: limit || undefined, offset: offset || undefined });
    res.json({
      proxies,
      stats: proxyRegistry.stats(),
    });
  });

  router.get('/job', (req, res) => {
    res.json(state.proxyValidationJob || { running: false });
  });

  router.post('/clear-dead', (req, res) => {
    const olderThanMs = parseInt(req.body?.olderThanMs, 10) || 0;
    const removed = proxyRegistry.pruneDead({ olderThanMs });
    if (removed > 0) proxyRegistry.save();
    res.json({ success: true, removed });
  });

  router.post('/retest', async (req, res) => {
    const onlyUnknown = !!req.body?.onlyUnknown;
    const onlyDead = !!req.body?.onlyDead;
    const target = req.body?.target || state.currentTarget || null;
    logger.info(`Re-testing ${onlyUnknown ? 'unknown' : onlyDead ? 'dead/degraded' : 'all'} proxies...`);
    const job = await proxyRegistry.retest({ onlyUnknown, onlyDead, target });
    res.json({ success: true, processed: job.processed, alive: job.alive, dead: job.dead });
  });

  router.post('/test-all', async (req, res) => {
    const target = req.body?.target || state.currentTarget || null;
    logger.info(`Re-testing all proxies...`);
    const job = await proxyRegistry.retest({ target });
    res.json({ success: true, processed: job.processed, alive: job.alive, dead: job.dead });
  });

  router.post('/retest/:key', async (req, res) => {
    const key = decodeURIComponent(req.params.key);
    const entry = proxyRegistry.find(key);
    if (!entry) return res.status(404).json({ error: 'Not found' });
    entry.status = 'retesting';
    const result = await proxyRegistry.validateProxy(entry, { target: state.currentTarget });
    if (result.alive) {
      proxyRegistry.markSuccess(key, result.latencyMs);
    } else {
      proxyRegistry.markFailure(key, 'manual-retest');
    }
    res.json({ success: true, alive: result.alive, latencyMs: result.latencyMs });
  });

  router.get('/inspect/:key', (req, res) => {
    const key = decodeURIComponent(req.params.key);
    const entry = proxyRegistry.find(key);
    if (!entry) return res.status(404).json({ error: 'Not found' });
    res.json({ proxy: entry });
  });

  router.post('/disable/:key', (req, res) => {
    const key = decodeURIComponent(req.params.key);
    if (!proxyRegistry.has(key)) return res.status(404).json({ error: 'Not found' });
    proxyRegistry.markFailure(key, 'manual-disable');
    proxyRegistry.setStatus(key, 'dead');
    proxyRegistry.save();
    res.json({ success: true });
  });

  router.delete('/:key', (req, res) => {
    const key = decodeURIComponent(req.params.key);
    if (!proxyRegistry.has(key)) return res.status(404).json({ error: 'Not found' });
    proxyRegistry.remove(key);
    proxyRegistry.save();
    res.json({ success: true });
  });

  router.get('/stats', (req, res) => {
    res.json(proxyRegistry.stats());
  });

  router.post('/strategy', (req, res) => {
    const strat = req.body?.strategy;
    const allowed = ['random', 'round-robin', 'least-used', 'best-score'];
    if (!allowed.includes(strat)) return res.status(400).json({ error: 'Invalid strategy', allowed });
    proxyRegistry.defaultStrategy = strat;
    res.json({ success: true, default: strat });
  });

  return router;
}

module.exports = { buildProxyRoutes };
