const { Router } = require('express');
const { authenticate, requireRole } = require('../middleware/auth');
const { pool } = require('../db/pool');
const {
  getCachedLicense,
  getLicenseStatus,
  cacheLicense,
  clearLicense,
  remoteValidate,
} = require('../license/license');

const router = Router();

// PUBLIC status — used by frontend License Activation page (no auth) so users can see
// the current license state on a locked system before logging in.
router.get('/public-status', (_req, res) => {
  const status = getLicenseStatus();
  res.json({
    active: status.active,
    expired: status.expired,
    expiresAt: status.expiresAt,
    licenseKey: status.licenseKey
      ? `${status.licenseKey.slice(0, 4)}****${status.licenseKey.slice(-4)}`
      : null,
  });
});

// Shared activation logic — requires remote to confirm `valid=true`.
// Offline fallback: only re-cache a key that was previously validated (same key in cache).
async function activateKey(rawKey) {
  if (!rawKey || typeof rawKey !== 'string' || rawKey.trim().length < 4) {
    return { ok: false, status: 400, body: { error: 'Invalid license key' } };
  }
  const key = rawKey.trim();
  const validation = await remoteValidate(key);

  // Case 1: Remote configured AND reachable
  if (validation.configured && validation.reachable) {
    if (!validation.ok) {
      return { ok: false, status: 502, body: { error: 'License server error', detail: `HTTP ${validation.status}` } };
    }
    if (validation.valid === false) {
      return { ok: false, status: 400, body: { error: 'License key rejected by license server', reason: validation.reason || 'invalid' } };
    }
    cacheLicense(key, validation.expiresAt ? { expiresAt: validation.expiresAt } : {});
    return { ok: true, status: 200, body: { success: true, message: 'License activated successfully' } };
  }

  // Case 2: Remote configured but unreachable (offline) — only allow re-activation
  // of an already-cached key. Random keys MUST NOT pass when offline.
  if (validation.configured && !validation.reachable) {
    const cached = getLicenseStatus();
    if (cached.licenseKey && cached.licenseKey === key && !cached.expired) {
      cacheLicense(key); // refresh local 7-day window
      return { ok: true, status: 200, body: { success: true, message: 'License re-activated from cache (offline)' } };
    }
    return {
      ok: false,
      status: 503,
      body: {
        error: 'License server unreachable',
        message: 'Cannot validate a new license key while offline. Connect to the internet and try again.',
      },
    };
  }

  // Case 3: No remote configured at all (LICENSE_VALIDATE_URL empty) — refuse to
  // accept arbitrary keys. Operator must configure the validator URL.
  return {
    ok: false,
    status: 503,
    body: {
      error: 'License validator not configured',
      message: 'LICENSE_VALIDATE_URL is not set on this backend. Configure it to point at the cPanel /api/license/validate endpoint.',
    },
  };
}

// PUBLIC activation — anyone with a valid license key can unlock the system.
// Required because before activation there are no users to authenticate as.
router.post('/public-activate', async (req, res) => {
  try {
    const result = await activateKey(req.body?.licenseKey);
    res.status(result.status).json(result.body);
  } catch (err) {
    console.error('[license/public-activate]', err);
    res.status(500).json({ error: 'Failed to activate license' });
  }
});

// AUTHENTICATED status (super_admin only) — same payload as public but kept for
// the admin License page so existing UI does not break.
router.get('/status', authenticate, requireRole('super_admin'), (_req, res) => {
  const status = getLicenseStatus();
  res.json({
    active: status.active,
    licenseKey: status.licenseKey
      ? `${status.licenseKey.slice(0, 4)}****${status.licenseKey.slice(-4)}`
      : null,
    expiresAt: status.expiresAt,
    expired: status.expired,
    lastChecked: status.lastChecked,
  });
});

router.post('/activate', authenticate, requireRole('super_admin'), async (req, res) => {
  try {
    const result = await activateKey(req.body?.licenseKey);
    res.status(result.status).json(result.body);
  } catch (err) {
    console.error('[license/activate]', err);
    res.status(500).json({ error: 'Failed to activate license' });
  }
});

router.post('/deactivate', authenticate, requireRole('super_admin'), (_req, res) => {
  try {
    clearLicense();
    res.json({ success: true, message: 'License deactivated' });
  } catch (err) {
    res.status(500).json({ error: 'Failed to deactivate license' });
  }
});

// ── PUBLIC: License validation endpoint (runs on cPanel) ──
// Local backends call this to confirm a license key is still active and to
// fetch the latest expiry date. Replaces the former Supabase edge function.
//
// Request:  POST { licenseKey: string }
// Response: 200 { valid: boolean, expiresAt: string|null, reason?: string, customerName?: string }
router.post('/validate', async (req, res) => {
  try {
    const key = typeof req.body?.licenseKey === 'string' ? req.body.licenseKey.trim() : '';
    if (!key || key.length < 4) {
      return res.status(400).json({ valid: false, reason: 'missing_key' });
    }

    const { rows } = await pool.query(
      `SELECT id, license_key, active, expires_at, customer_name, validation_count
       FROM license_keys WHERE license_key = $1 LIMIT 1`,
      [key],
    );
    const data = rows[0];
    if (!data) return res.json({ valid: false, reason: 'not_found', expiresAt: null });
    if (!data.active) return res.json({ valid: false, reason: 'revoked', expiresAt: data.expires_at });

    const now = Date.now();
    const expiresAt = data.expires_at ? new Date(data.expires_at).getTime() : null;
    if (expiresAt !== null && expiresAt <= now) {
      return res.json({ valid: false, reason: 'expired', expiresAt: data.expires_at });
    }

    // Best-effort usage tracking
    pool.query(
      `UPDATE license_keys SET last_validated_at = NOW(),
        validation_count = COALESCE(validation_count, 0) + 1 WHERE id = $1`,
      [data.id],
    ).catch(() => {});

    res.json({
      valid: true,
      expiresAt: data.expires_at,
      customerName: data.customer_name,
    });
  } catch (err) {
    console.error('[license/validate]', err);
    res.status(500).json({ valid: false, reason: 'internal_error' });
  }
});

module.exports = router;
