'use strict';

const fs = require('fs');
const path = require('path');
const { getAgentConfig, isConfigured, resolveConfigPath, readConnectorConfig } = require('../src/agent/agentConfig');
const { authHeaders } = require('../src/agent/agentAuth');
const { sendHeartbeat } = require('../src/agent/syncClient');

function mask(value) {
  const text = String(value || '');
  if (!text) return null;
  if (text.length <= 8) return '****';
  return `${text.slice(0, 4)}****${text.slice(-4)}`;
}

function arg(name) {
  const flag = `--${name}`;
  const index = process.argv.indexOf(flag);
  if (index >= 0) return process.argv[index + 1] || '';
  const prefixed = process.argv.find((item) => item.startsWith(`${flag}=`));
  return prefixed ? prefixed.slice(flag.length + 1) : '';
}

async function fetchJson(url, timeoutMs = 10000) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeoutMs);
  try {
    const response = await fetch(url, { signal: controller.signal, headers: { accept: 'application/json' } });
    const text = await response.text();
    const payload = text ? JSON.parse(text) : {};
    return { ok: response.ok && payload.ok !== false, status: response.status, payload };
  } finally {
    clearTimeout(timer);
  }
}

function serviceStatus(name = 'ArkhonMonitorConnector') {
  if (process.platform !== 'win32') return { ok: true, skipped: true, reason: 'not_windows' };
  try {
    const { execFileSync } = require('child_process');
    const stdout = execFileSync('sc.exe', ['query', name], { timeout: 5000, windowsHide: true }).toString();
    const state = (stdout.match(/(?:STATE|ESTADO)\s*:\s*\d+\s+([A-Z_]+)/i) || [])[1] || '';
    return { ok: /RUNNING/i.test(state), installed: true, running: /RUNNING/i.test(state), state };
  } catch (error) {
    return { ok: false, installed: false, running: false, error: error.message };
  }
}

function checkHmac(config) {
  try {
    const headers = authHeaders(config, {
      method: 'POST',
      path: '/api/agent/heartbeat',
      body: JSON.stringify({ status: 'diagnostic' }),
    });
    return {
      ok: Boolean(headers['x-agent-signature'] && headers['x-agent-key-id']),
      signed: Boolean(headers['x-agent-signature']),
      protocol: headers['x-arkhon-protocol'],
      agentId: mask(headers['x-agent-id']),
      agentKeyId: mask(headers['x-agent-key-id']),
    };
  } catch (error) {
    return { ok: false, error: error.message };
  }
}

async function main() {
  if (arg('configPath') || arg('config-path')) process.env.CONFIG_PATH = arg('configPath') || arg('config-path');
  const configPath = resolveConfigPath();
  const connectorPath = path.join(configPath, 'connector.json');
  const secretPath = path.join(configPath, 'connector-secret.enc');
  const connector = readConnectorConfig(configPath);
  const config = getAgentConfig();
  if (arg('cloudUrl') || arg('cloud-url')) config.cloudUrl = String(arg('cloudUrl') || arg('cloud-url')).replace(/\/+$/, '');

  const checks = {
    connectorJson: { ok: fs.existsSync(connectorPath), path: connectorPath },
    encryptedSecret: { ok: fs.existsSync(secretPath), path: secretPath },
    identity: {
      ok: Boolean(config.tenantId && config.branchId && config.agentId && config.agentKeyId),
      tenantId: mask(config.tenantId),
      branchId: mask(config.branchId),
      agentId: mask(config.agentId),
      agentKeyId: mask(config.agentKeyId),
      branchName: connector.branch_name || connector.branchName || null,
    },
    secretReadable: { ok: Boolean(config.agentKey), encrypted: true },
    hmac: checkHmac(config),
    service: serviceStatus(),
    softrestaurant: { ok: true, status: process.env.DB_SERVER ? 'configured' : 'pending', message: process.env.DB_SERVER ? 'SoftRestaurant configurado.' : 'SoftRestaurant pendiente de configurar.' },
  };

  if (config.cloudUrl) {
    try {
      const health = await fetchJson(`${config.cloudUrl}/health`);
      checks.cloudHealth = { ok: health.ok, status: health.status };
    } catch (error) {
      checks.cloudHealth = { ok: false, error: 'No se pudo conectar con ARKHON Cloud.' };
    }
  } else {
    checks.cloudHealth = { ok: false, error: 'URL Cloud no configurada.' };
  }

  if (isConfigured(config)) {
    try {
      const heartbeat = await sendHeartbeat(config, {
        agent_id: config.agentId,
        tenant_id: config.tenantId,
        branch_id: config.branchId,
        hardware_id: config.hardwareId || config.deviceId || null,
        status: 'diagnostic',
        timestamp: new Date().toISOString(),
      });
      checks.heartbeat = { ok: heartbeat?.ok !== false, status: heartbeat?.status || 'ok' };
    } catch (error) {
      checks.heartbeat = { ok: false, error: error.message };
    }
  } else {
    checks.heartbeat = { ok: false, error: 'Identidad del conector incompleta.' };
  }

  const ok = Object.values(checks).every((check) => check && check.ok !== false);
  const output = {
    ok,
    configPath,
    cloudUrl: config.cloudUrl || null,
    checks,
  };
  process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
  process.exit(ok ? 0 : 1);
}

main().catch((error) => {
  process.stderr.write(`${JSON.stringify({ ok: false, error: error.message }, null, 2)}\n`);
  process.exit(1);
});
