'use strict';

const fs = require('fs');
const path = require('path');

function getConfigDir() {
  return process.env.CONFIG_PATH || path.join(process.env.ProgramData || 'C:\\ProgramData', 'ARKHON', 'Agent', 'config');
}

function getSetupStatePath(configDir = getConfigDir()) {
  return path.join(configDir, 'setup-state.json');
}

function readSetupState(configDir = getConfigDir()) {
  try {
    const file = getSetupStatePath(configDir);
    if (!fs.existsSync(file)) return { configured: false, path: file };
    const state = JSON.parse(fs.readFileSync(file, 'utf8'));
    return { ...state, configured: state.configured === true, path: file };
  } catch (error) {
    return { configured: false, error: error.message, path: getSetupStatePath(configDir) };
  }
}

function isSetupComplete(configDir = getConfigDir()) {
  return readSetupState(configDir).configured === true;
}

function writeSetupComplete({ version, configDir = getConfigDir(), completedAt = new Date().toISOString() } = {}) {
  const file = getSetupStatePath(configDir);
  const payload = {
    configured: true,
    stage: 'completed',
    pending: false,
    completedAt,
    version: version || '',
  };
  fs.mkdirSync(path.dirname(file), { recursive: true });
  fs.writeFileSync(file, JSON.stringify(payload, null, 2), 'utf8');
  return { ...payload, path: file };
}

function writeSetupPending({ version, configDir = getConfigDir(), reason = 'setup_not_completed', updatedAt = new Date().toISOString() } = {}) {
  const file = getSetupStatePath(configDir);
  const current = readSetupState(configDir);
  if (current.configured === true) return current;
  const payload = {
    configured: false,
    stage: 'pending_setup',
    pending: true,
    code: 'setup_not_completed',
    reason,
    createdAt: current.createdAt || updatedAt,
    updatedAt,
    version: version || '',
  };
  fs.mkdirSync(path.dirname(file), { recursive: true });
  fs.writeFileSync(file, JSON.stringify(payload, null, 2), 'utf8');
  return { ...payload, path: file };
}

function isSetupRoute(pathname) {
  return pathname === '/admin-setup' || pathname.startsWith('/admin-setup/');
}

function isSetupAllowedPath(pathname) {
  if (!pathname) return false;
  if (isSetupRoute(pathname)) return true;
  if (pathname === '/login') return true;
  if (/\.(?:css|js|png|jpg|jpeg|gif|svg|ico|webp|woff2?)$/i.test(pathname)) return true;
  if (pathname === '/api/app-info') return true;
  if (pathname === '/api/login-config') return true;
  if (pathname === '/api/health' || pathname === '/api/ping' || pathname === '/ping') return true;
  if (pathname === '/api/local-token') return true;
  if (pathname === '/api/auth/login-admin' || pathname === '/api/auth/refresh' || pathname === '/api/auth/logout') return true;
  if (pathname === '/api/admin/config' || pathname === '/api/admin/test-db' || pathname === '/api/admin/cloudflare-status') return true;
  if (pathname === '/api/admin/setup-complete') return true;
  if (pathname === '/api/admin/licencia' || pathname.startsWith('/api/admin/licencia/')) return true;
  if (pathname === '/api/security/permissions' || pathname === '/api/security/profiles' || pathname === '/api/security/users') return true;
  if (pathname.startsWith('/api/security/profiles/') || pathname.startsWith('/api/security/users/')) return true;
  if (pathname.startsWith('/api/security/password-policy/')) return true;
  return false;
}

function isHtmlRequest(req) {
  const accept = String(req.headers?.accept || '');
  return req.method === 'GET' && (accept.includes('text/html') || !req.path.startsWith('/api/'));
}

function setupGate(req, res, next) {
  if (isSetupComplete()) return next();
  if (isSetupAllowedPath(req.path)) return next();
  if (isHtmlRequest(req)) return res.redirect(302, `/login?setup=1&next=${encodeURIComponent(req.originalUrl || '/')}`);
  return res.status(423).json({
    ok: false,
    code: 'setup_incomplete',
    error: 'Configurador pendiente. Completa /admin-setup antes de operar ARKHON.',
  });
}

module.exports = {
  getConfigDir,
  getSetupStatePath,
  readSetupState,
  isSetupComplete,
  writeSetupComplete,
  writeSetupPending,
  isSetupAllowedPath,
  setupGate,
};
