const fs = require("fs");
const path = require("path");
const { parseIntent, matchKeywords } = require("./intent-parser");
const { routeCapability } = require("./capability-router");
const { buildExecutionPolicy } = require("./execution-policy");
const { resolveMemoryStrategy } = require("./context-memory-bridge");
const { appendRouteEvents } = require("./event-log");
const { disabledSet } = require("./disabled-skills");
const { formatExplanationCard } = require("./explanation");

const WEIGHT_EMOJI = { light: "🟢", medium: "🟡", heavy: "🔴" };

function loadMatrix(rootDir) {
  const p = path.join(rootDir, "skill-routing-matrix.json");
  if (!fs.existsSync(p)) return null;
  return JSON.parse(fs.readFileSync(p, "utf-8"));
}

function loadRegistry(rootDir) {
  const p = path.join(rootDir, "registry.json");
  if (!fs.existsSync(p)) return { core: [], recommended: [], optional: [], project_added: [] };
  return JSON.parse(fs.readFileSync(p, "utf-8"));
}

function installedSkills(rootDir, registry) {
  const skillsDir = path.join(rootDir, "skills");
  const names = new Set([
    ...(registry.core || []),
    ...(registry.recommended || []),
    ...(registry.optional || []),
    ...(registry.project_added || [])
  ]);
  const onDisk = [];
  if (fs.existsSync(skillsDir)) {
    for (const name of fs.readdirSync(skillsDir)) {
      if (fs.existsSync(path.join(skillsDir, name, "SKILL.md"))) {
        onDisk.push(name);
      }
    }
  }
  return [...names].filter((n) => onDisk.includes(n));
}

function loadFeatureFlags(rootDir) {
  const p = path.join(rootDir, ".capint", "context.json");
  if (!fs.existsSync(p)) return {};
  try {
    const ctx = JSON.parse(fs.readFileSync(p, "utf-8"));
    return ctx.feature_flags || {};
  } catch {
    return {};
  }
}

function routeTask(text, rootDir) {
  const matrix = loadMatrix(rootDir);
  if (!matrix) return { error: "skill-routing-matrix.json not found" };

  const registry = loadRegistry(rootDir);
  const installed = installedSkills(rootDir, registry);
  const disabled = disabledSet(rootDir);
  const parsedIntent = parseIntent(text, matrix);
  const routeResult = routeCapability(
    parsedIntent,
    matrix,
    registry,
    installed,
    matchKeywords,
    disabled
  );
  const memoryStrategy = resolveMemoryStrategy({
    intent: parsedIntent,
    routeResult,
    matrix,
    rootDir,
    featureFlags: loadFeatureFlags(rootDir)
  });
  const executionIntent = buildExecutionPolicy({
    rawText: text,
    routeResult,
    memoryStrategy,
    matrix,
    parsedIntent,
    rootDir
  });

  const routeEvents = [
    ...(memoryStrategy.events || []),
    {
      type: "route.provider_selected",
      resolution: executionIntent.resolution,
      capability: executionIntent.capability,
      weight: routeResult.overall
    }
  ];
  const eventLog = appendRouteEvents(rootDir, routeEvents);

  return {
    request: text,
    overall_weight: routeResult.overall,
    overall_emoji: WEIGHT_EMOJI[routeResult.overall],
    show_skill_plan: routeResult.showPlan,
    subtasks: routeResult.rows,
    installed_count: installed.length,
    execution_intent: executionIntent,
    events: routeEvents,
    event_log: eventLog
  };
}

function formatTextReport(result, options = {}) {
  if (result.error) return result.error;
  const { verbose = false } = options;
  const lines = [];
  lines.push("");
  lines.push("## Execution Intent");
  lines.push("");
  lines.push(`Intent: ${result.execution_intent.intent}`);
  lines.push(`Capability: ${result.execution_intent.capability}`);
  lines.push(`Resolution: ${result.execution_intent.resolution}`);
  if (result.execution_intent.resolution_status) {
    lines.push(`Resolution status: ${result.execution_intent.resolution_status}`);
    if (result.execution_intent.resolution_hint) {
      lines.push(`Hint: ${result.execution_intent.resolution_hint}`);
    }
  }
  lines.push(`Memory: ${result.execution_intent.memory}`);
  lines.push(`Plan: ${result.execution_intent.plan}`);
  if (result.execution_intent.confirm?.enabled) {
    const optionSummary = (result.execution_intent.confirm_options || []).map((o) => o.id).join("|");
    lines.push(`Confirm: ${result.execution_intent.confirm_question}`);
    lines.push(`Options: ${optionSummary} (default: ${result.execution_intent.confirm_default_option})`);
  }
  lines.push("");
  if (result.execution_intent.fallback) {
    lines.push(`Fallback capability: ${result.execution_intent.fallback.capability}`);
    lines.push(`Override: ${result.execution_intent.fallback.override}`);
    lines.push("");
  }
  if (result.execution_intent.verification_required) {
    lines.push(`Verification: required (${result.execution_intent.verification_profile || "standard"})`);
    for (const h of result.execution_intent.verification_hints || []) {
      lines.push(`  - ${h}`);
    }
    lines.push("");
  }
  if (result.execution_intent.orchestration) {
    const o = result.execution_intent.orchestration;
    lines.push(`Orchestration: ${o.pattern} (${o.execution_mode})`);
    if (o.chains?.length) {
      lines.push(`Chains: ${o.chains.map((c) => c.then_capability).join(" → ")}`);
    }
    lines.push("");
  }
  if (result.execution_intent.context_pack?.snippets?.length) {
    lines.push(`Context pack: ${result.execution_intent.context_pack.snippets.length} local snippet(s)`);
    lines.push("");
  }
  if (result.execution_intent.workspace_boundary?.violated) {
    lines.push(`Workspace boundary: ${result.execution_intent.workspace_boundary.override_hint}`);
    lines.push("");
  }
  lines.push(`Weight: ${result.overall_emoji} ${result.overall_weight}`);
  lines.push(`Plan visible: ${result.show_skill_plan ? "yes" : "no"}`);

  const explanation = result.execution_intent.explanation;
  if (explanation) {
    lines.push(...formatExplanationCard(explanation));
  }

  if (verbose) {
    const ex = result.execution_intent.route_explain;
    if (ex) {
      lines.push("");
      lines.push("## Route explain (verbose)");
      lines.push(`Matched task type: ${ex.matched_task_type || "—"}`);
      lines.push(`Resolver order: ${(ex.resolver_order || []).join(" → ")}`);
      if (ex.winner) {
        lines.push(`Winner: ${ex.winner.name}/${ex.winner.resource} (confidence ${ex.winner.confidence})`);
      }
      lines.push("");
    }
    lines.push("## Skill Plan (verbose)");
    lines.push("| # | Subtask | Weight | Reason | Skills | Workflow |");
    lines.push("|---|---------|--------|--------|--------|----------|");
    for (const r of result.subtasks) {
      lines.push(
        `| ${r.index} | ${r.subtask} | ${r.emoji} | ${r.reason} | ${r.skills.map((s) => s.name).join(", ")} | ${r.workflow || "—"} |`
      );
    }
  }
  lines.push("");
  return lines.join("\n");
}

function listCheatsheet(matrix) {
  const lines = ["capability/providers from skill-routing-matrix.json", ""];
  for (const tt of matrix?.task_types || []) {
    const capability = tt.capability || tt.id;
    const providerList = (tt.providers || []).map((p) => `${p.name}/${p.resource}`).join(", ");
    lines.push(`  ${tt.id.padEnd(20)} -> ${capability}${providerList ? ` | ${providerList}` : ""}`);
  }
  return lines.join("\n");
}

module.exports = {
  routeTask,
  formatTextReport,
  listCheatsheet,
  loadMatrix
};
