import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { getDb, newId, nowIso } from '../db.js';
import { appendComplianceAudit } from '../compliance-audit.js';

const TOOL_NAME = 'mines_data_import';
const SCOPE_KEY = 'directory_root';
const SECRET_SEGMENTS = new Set(['.ssh']);
const DEFAULT_ORG_ID = 'personal-org';

function isInside(child, parent) {
  const rel = path.relative(parent, child);
  return rel === '' || (!!rel && !rel.startsWith('..') && !path.isAbsolute(rel));
}

function hasBlockedSegment(absPath) {
  const parts = absPath.split(path.sep).filter(Boolean);
  if (parts.some(part => SECRET_SEGMENTS.has(part))) return true;
  const base = path.basename(absPath);
  return base === '.env.local' || /^\.env($|\.)/.test(base);
}

function orgIdFor(options = {}) {
  return options.org_id || DEFAULT_ORG_ID;
}

function safeRealpath(absPath) {
  try {
    return fs.realpathSync.native ? fs.realpathSync.native(absPath) : fs.realpathSync(absPath);
  } catch {
    return path.resolve(absPath);
  }
}

function isBroadOrSystemRoot(absPath) {
  const root = path.parse(absPath).root;
  if (absPath === root) return true;

  const home = safeRealpath(os.homedir?.() || '');
  if (home && absPath === home) return true;

  const broad = new Set([
    '/Users',
    '/System',
    '/Library',
    '/Applications',
    '/private',
    '/var',
    '/etc',
    '/tmp',
    '/private/tmp',
    process.cwd(),
  ].filter(Boolean).map(p => path.resolve(p)));
  if (broad.has(absPath)) return true;

  if (home) {
    const immediateHomeDirs = new Set(['Desktop', 'Documents', 'Downloads']);
    if (path.dirname(absPath) === home && immediateHomeDirs.has(path.basename(absPath))) return true;
  }

  return false;
}

function realpathIfPresent(absPath) {
  const resolved = path.resolve(String(absPath || '.'));
  if (fs.existsSync(resolved)) return safeRealpath(resolved);
  const missing = [];
  let current = resolved;
  while (!fs.existsSync(current)) {
    missing.unshift(path.basename(current));
    const parent = path.dirname(current);
    if (parent === current) return resolved;
    current = parent;
  }
  return path.join(safeRealpath(current), ...missing);
}

export function normalizeMinesImportRoot(inputPath) {
  if (!String(inputPath || '').trim()) {
    return { ok: false, error: 'directory_root_required' };
  }
  const rootPath = realpathIfPresent(path.resolve(String(inputPath || '').trim()));
  if (hasBlockedSegment(rootPath)) {
    return { ok: false, error: 'blocked_path', root_path: rootPath };
  }
  if (isBroadOrSystemRoot(rootPath)) {
    return { ok: false, error: 'root_too_broad', root_path: rootPath };
  }
  let stat;
  try {
    stat = fs.statSync(rootPath);
  } catch {
    return { ok: false, error: 'directory_not_found', root_path: rootPath };
  }
  if (!stat.isDirectory()) {
    return { ok: false, error: 'not_a_directory', root_path: rootPath };
  }
  return { ok: true, root_path: rootPath };
}

export function listMinesImportRoots(options = {}) {
  const orgId = orgIdFor(options);
  const rows = getDb().prepare(`
    SELECT id, scope_value AS root_path, label, created_at, org_id, created_by_user_id
    FROM tool_allowlists
    WHERE tool_name = ? AND scope_key = ? AND COALESCE(org_id, ?) = ?
    ORDER BY created_at DESC
  `).all(TOOL_NAME, SCOPE_KEY, orgId, orgId);

  return rows.map(row => ({
    id: row.id,
    root_path: row.root_path,
    label: row.label || path.basename(row.root_path) || row.root_path,
    created_at: row.created_at,
    org_id: row.org_id || orgId,
    created_by_user_id: row.created_by_user_id || null,
  }));
}

export function approveMinesImportRoot(inputPath, options = {}) {
  const normalized = normalizeMinesImportRoot(inputPath);
  if (!normalized.ok) return { status: 'error', error: normalized.error, root_path: normalized.root_path || null };

  const db = getDb();
  const now = nowIso();
  const orgId = orgIdFor(options);
  const existing = db.prepare(`
    SELECT id, label, created_at, org_id, created_by_user_id
    FROM tool_allowlists
    WHERE tool_name = ? AND scope_key = ? AND scope_value = ? AND COALESCE(org_id, ?) = ?
  `).get(TOOL_NAME, SCOPE_KEY, normalized.root_path, orgId, orgId);

  if (existing) {
    return {
      status: 'ok',
      root_path: normalized.root_path,
      id: existing.id,
      existing: true,
      label: existing.label,
      created_at: existing.created_at,
      org_id: existing.org_id || orgId,
      created_by_user_id: existing.created_by_user_id || null,
    };
  }

  const id = newId('mir');
  const label = options.label || path.basename(normalized.root_path) || 'Mine import root';
  db.prepare(`
    INSERT INTO tool_allowlists (id, tool_name, scope_key, scope_value, org_id, created_by_user_id, label, created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?)
  `).run(id, TOOL_NAME, SCOPE_KEY, normalized.root_path, orgId, options.user_id || null, label, now);

  try {
    appendComplianceAudit({
      user_id: options.acting_on_behalf_of_user_id || options.user_id || 'system',
      org_id: orgId,
      action: 'mines.import_root.approved',
      status: 'success',
      summary: 'Approved Mines import root: ' + normalized.root_path,
      action_target_id: id,
      action_target_type: 'tool_allowlist',
      meta: { root_path: normalized.root_path, label, org_id: orgId },
    });
  } catch { /* non-fatal */ }

  return { status: 'ok', root_path: normalized.root_path, id, existing: false, label, created_at: now, org_id: orgId };
}

export function removeMinesImportRoot(id, options = {}) {
  const db = getDb();
  const orgId = orgIdFor(options);
  const row = db.prepare(`
    SELECT id, scope_value AS root_path
    FROM tool_allowlists
    WHERE id = ? AND tool_name = ? AND scope_key = ? AND COALESCE(org_id, ?) = ?
  `).get(String(id || ''), TOOL_NAME, SCOPE_KEY, orgId, orgId);
  if (!row) return { status: 'error', error: 'not_found' };
  db.prepare('DELETE FROM tool_allowlists WHERE id = ?').run(row.id);
  try {
    appendComplianceAudit({
      user_id: options.acting_on_behalf_of_user_id || options.user_id || 'system',
      org_id: orgId,
      action: 'mines.import_root.removed',
      status: 'success',
      summary: 'Removed Mines import root: ' + row.root_path,
      action_target_id: row.id,
      action_target_type: 'tool_allowlist',
      meta: { root_path: row.root_path, org_id: orgId },
    });
  } catch { /* non-fatal */ }
  return { status: 'ok', id: row.id, root_path: row.root_path };
}

export function isInsideApprovedMinesImportRoot(inputPath, options = {}) {
  const checked = realpathIfPresent(path.resolve(String(inputPath || '.')));
  if (hasBlockedSegment(checked)) return false;
  return listMinesImportRoots(options).some(root => {
    // Compare against the canonical path that was approved. Do not re-realpath
    // the stored root at use time; if an approved folder is later replaced by a
    // symlink to a different target, the import path realpath will no longer be
    // contained by this stored canonical root and the check fails closed.
    const rootPath = path.resolve(root.root_path);
    return isInside(checked, rootPath);
  });
}
