import fs from 'fs';
import path from 'path';
import { getTrafficRules, getTrafficRule, updateTrafficRule } from './unifiClient.js';

const DATA_PATH = '/data/policy_map.json';

const DEFAULT_CATEGORIES = {
  'Social Media': { ruleIds: [], icon: 'social' },
  'Streaming': { ruleIds: [], icon: 'streaming' },
  'Adult Content': { ruleIds: [], icon: 'adult' },
  'Gaming': { ruleIds: [], icon: 'gaming' },
};

let policyMap = {};

export function loadPolicies() {
  try {
    if (fs.existsSync(DATA_PATH)) {
      const raw = fs.readFileSync(DATA_PATH, 'utf-8');
      policyMap = JSON.parse(raw);
      console.log('[PolicyEngine] Loaded policy map from disk');
    } else {
      policyMap = structuredClone(DEFAULT_CATEGORIES);
      savePolicies();
      console.log('[PolicyEngine] Created default policy map');
    }
  } catch (err) {
    console.error('[PolicyEngine] Error loading policies:', err.message);
    policyMap = structuredClone(DEFAULT_CATEGORIES);
  }
}

function savePolicies() {
  const dir = path.dirname(DATA_PATH);
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
  fs.writeFileSync(DATA_PATH, JSON.stringify(policyMap, null, 2));
}

export async function getCategories() {
  const allRules = await getTrafficRules();
  const ruleList = Array.isArray(allRules) ? allRules : allRules?.data || [];
  const ruleMap = new Map(ruleList.map((r) => [r._id, r]));

  const categories = {};
  for (const [name, config] of Object.entries(policyMap)) {
    const rules = config.ruleIds.map((id) => {
      const rule = ruleMap.get(id);
      return {
        id,
        name: rule?.description || rule?.name || id,
        enabled: rule?.enabled ?? false,
      };
    });
    // Category is "allowed" when ALL its rules are disabled (not blocking)
    const allDisabled = rules.length === 0 || rules.every((r) => !r.enabled);
    categories[name] = {
      icon: config.icon,
      ruleIds: config.ruleIds,
      rules,
      allowed: allDisabled,
    };
  }
  return categories;
}

export async function toggleCategory(categoryName, allowed) {
  const config = policyMap[categoryName];
  if (!config) throw new Error(`Category "${categoryName}" not found`);

  const results = [];
  for (const ruleId of config.ruleIds) {
    const rule = await getTrafficRule(ruleId);
    if (!rule) {
      results.push({ ruleId, success: false, error: 'Rule not found' });
      continue;
    }
    // Inversion: UI "allowed" = rule disabled, UI "blocked" = rule enabled
    rule.enabled = !allowed;
    try {
      await updateTrafficRule(ruleId, rule);
      results.push({ ruleId, success: true });
    } catch (err) {
      results.push({ ruleId, success: false, error: err.message });
    }
  }
  return results;
}

export function assignRules(categoryName, ruleIds) {
  if (!policyMap[categoryName]) {
    policyMap[categoryName] = { ruleIds: [], icon: 'custom' };
  }
  policyMap[categoryName].ruleIds = ruleIds;
  savePolicies();
  return policyMap[categoryName];
}

export function addCategory(name, icon = 'custom') {
  if (policyMap[name]) throw new Error(`Category "${name}" already exists`);
  policyMap[name] = { ruleIds: [], icon };
  savePolicies();
  return policyMap[name];
}

export function deleteCategory(name) {
  if (!policyMap[name]) throw new Error(`Category "${name}" not found`);
  delete policyMap[name];
  savePolicies();
}
