// ─────────────────────────────────────────────────────────────
//  DomainHarvest — License Module  (license.js)
//  Handles: verify, cache, plan limits, feature gating
// ─────────────────────────────────────────────────────────────

const LICENSE_API = 'https://domainharvest-backend-production.up.railway.app';
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour

// ── Plan feature definitions ────────────────────────────────
const PLAN_CONFIG = {
  free: {
    label: 'Free',
    maxPages: 3,
    exportFormats: ['csv'],
    canScrapeAll: true,       // yes but page-limited
    canDedup: false,
    canScore: false,
    canFavorites: false,
    canTemplates: false,
    canXlsx: false,
    color: '#8b9bb4'
  },
  pro: {
    label: 'Pro',
    maxPages: 5,
    exportFormats: ['csv', 'xlsx'],
    canScrapeAll: true,
    canDedup: true,
    canScore: true,
    canFavorites: true,
    canTemplates: true,
    canXlsx: true,
    color: '#00ffaa'
  }
};

// ── Verify license key against API ──────────────────────────
async function verifyLicenseKey(key) {
  try {
    const extId = chrome.runtime.id;
    const resp = await fetch(`${LICENSE_API}/api/license/verify?key=${encodeURIComponent(key)}&ext_id=${encodeURIComponent(extId)}`,{
      method: 'GET',
      headers: { 'Content-Type': 'application/json' }
    });

    if (!resp.ok) {
      if (resp.status === 429) return { valid: false, error: 'Too many requests. Please wait a moment.' };
      if (resp.status === 403) return { valid: false, error: 'License key is inactive or expired.' };
      return { valid: false, error: 'Server error. Please try again.' };
    }

    const data = await resp.json();
    return data; // { valid, plan, expiresAt, email }
  } catch (err) {
    // Network error — use cached data if available
    console.warn('License API unreachable:', err.message);
    return { valid: false, error: 'Cannot reach license server. Check your internet connection.' };
  }
}

// ── Load cached license from storage ───────────────────────
async function getCachedLicense() {
  return new Promise(resolve => {
    chrome.storage.local.get(['licenseData'], result => {
      resolve(result.licenseData || null);
    });
  });
}

// ── Save license to cache ───────────────────────────────────

async function cacheLicense(data) {
  // Si le plan a changé, vider l'ancien cache
  const old = await getCachedLicense();
  if (old && old.plan !== data.plan) {
    await new Promise(resolve => chrome.storage.local.remove(['licenseData'], resolve));
  }
  const payload = { ...data, cachedAt: Date.now() };
  return new Promise(resolve => {
    chrome.storage.local.set({ licenseData: payload }, resolve);
  });
}

// ── Clear stored license ────────────────────────────────────
async function clearLicense() {
  return new Promise(resolve => {
    chrome.storage.local.remove(['licenseData', 'licenseKey'], resolve);
  });
}

// ── Check if cache is still valid ──────────────────────────
function isCacheValid(cached) {
  if (!cached || !cached.cachedAt) return false;
  return (Date.now() - cached.cachedAt) < CACHE_TTL_MS;
}

// ── Main: get current plan (from cache or fresh verify) ─────
async function getCurrentPlan() {
  // 1. Try to get key from storage
  const stored = await new Promise(resolve => {
    chrome.storage.local.get(['licenseKey', 'licenseData'], resolve);
  });

  const key = stored.licenseKey;

  // 2. No key at all → free plan (unregistered)
  if (!key) {
    return { plan: 'free', valid: false, registered: false };
  }

  // 3. Cache still fresh? Use it
  if (isCacheValid(stored.licenseData) && stored.licenseData.valid) {
    return { ...stored.licenseData, registered: true };
  }

  // 4. Cache expired or invalid → re-verify
  const result = await verifyLicenseKey(key);

  if (result.valid) {
    await cacheLicense({ ...result, key });
    return { ...result, registered: true };
  }

  // 5. Verification failed but we have an old valid cache → grace period (offline)
  if (stored.licenseData && stored.licenseData.valid) {
    console.warn('Using stale license cache (API unavailable)');
    return { ...stored.licenseData, registered: true, stale: true };
  }

  // 6. Key is invalid
  return { plan: 'free', valid: false, registered: true, error: result.error };
}

// ── Activate a new key ──────────────────────────────────────
async function activateLicenseKey(key) {
  const trimmed = key.trim().toUpperCase();

  if (!trimmed || trimmed.length < 10) {
    return { success: false, error: 'Invalid key format.' };
  }

  const result = await verifyLicenseKey(trimmed);

  if (result.valid) {
    await new Promise(resolve => chrome.storage.local.set({ licenseKey: trimmed }, resolve));
    await cacheLicense({ ...result, key: trimmed });
    return { success: true, plan: result.plan, email: result.email };
  }

  return { success: false, error: result.error || 'Invalid license key.' };
}

// ── Get plan config object ──────────────────────────────────
function getPlanConfig(plan) {
  return PLAN_CONFIG[plan] || PLAN_CONFIG.free;
}

// ── Compute domain score ────────────────────────────────────
function scoreDomain(domain) {
  let score = 0;
  const bl = parseInt(domain.BL) || 0;
  const dp = parseInt(domain.DP) || 0;
  const wby = parseInt(domain.WBY) || new Date().getFullYear();
  const age = new Date().getFullYear() - wby;

  score += Math.min(bl * 0.3, 30);       // Backlinks: max 30
  score += Math.min(dp * 0.2, 20);       // Domain Popularity: max 20
  score += Math.min(age * 2, 20);        // Age: max 20
  if (domain.ACR && domain.ACR !== '-') score += 15; // Alexa rank
  if (domain.Dmoz === 'Y') score += 10;  // Dmoz listing
  if (domain.domain && domain.domain.endsWith('.com')) score += 5; // TLD bonus

  return Math.round(Math.min(score, 100));
}

// ── Deduplicate domains by name ─────────────────────────────
function deduplicateDomains(domains) {
  const seen = new Set();
  return domains.filter(d => {
    const key = (d.domain || '').toLowerCase().trim();
    if (!key || seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}
