import { resultToMcpResponse } from '../utils/result-adapter.js';
import { resolveProjectConfig } from '../utils/config-resolver.js';
import { sanitizePath } from '../utils/sanitize-path.js';

export const checkDependenciesDefinition = {
  name: 'check_dependencies',
  description: 'Validate layer boundaries and detect circular dependencies',
  inputSchema: {
    type: 'object' as const,
    properties: {
      path: { type: 'string', description: 'Path to project root' },
    },
    required: ['path'],
  },
};

export async function handleCheckDependencies(input: { path: string }) {
  let projectPath: string;
  try {
    projectPath = sanitizePath(input.path);
  } catch (error) {
    return {
      content: [
        {
          type: 'text' as const,
          text: `Error: ${error instanceof Error ? error.message : String(error)}`,
        },
      ],
      isError: true,
    };
  }
  const configResult = resolveProjectConfig(projectPath);
  if (!configResult.ok) return resultToMcpResponse(configResult);

  // Delegate to core library
  try {
    const { validateDependencies, TypeScriptParser } = await import('@harness-engineering/core');
    const config = configResult.value as Record<string, unknown>;
    const rawLayers = (Array.isArray(config.layers) ? config.layers : []) as Array<{
      name: string;
      pattern: string;
      allowedDependencies: string[];
    }>;
    const layers = rawLayers.map((l) => ({
      name: l.name,
      patterns: [l.pattern],
      allowedDependencies: l.allowedDependencies,
    }));
    const parser = new TypeScriptParser();

    // Attempt to load graph for enhanced validation
    const { loadGraphStore } = await import('../utils/graph-loader.js');
    const store = await loadGraphStore(projectPath);
    let graphDependencyData;
    if (store) {
      const { GraphConstraintAdapter } = await import('@harness-engineering/graph');
      const adapter = new GraphConstraintAdapter(store);
      const graphData = adapter.computeDependencyGraph();
      graphDependencyData = {
        nodes: [...graphData.nodes],
        edges: graphData.edges.map((e) => ({ ...e })),
      };
    }

    const result = await validateDependencies({
      layers,
      rootDir: projectPath,
      parser,
      ...(graphDependencyData !== undefined && { graphDependencyData }),
    });

    // Run design constraint checks when design tokens exist in the graph
    let designViolations: Array<{
      code: string;
      file: string;
      message: string;
      severity: string;
    }> = [];
    if (store) {
      const designTokenNodes = store.findNodes({ type: 'design_token' as never });
      if (designTokenNodes.length > 0) {
        const { DesignConstraintAdapter } = await import('@harness-engineering/graph');
        const designAdapter = new DesignConstraintAdapter(store);
        const fileNodes = store.findNodes({ type: 'file' });
        for (const fileNode of fileNodes) {
          const filePath = fileNode.path ?? fileNode.id;
          if (!/\.(tsx?|jsx?|css|scss|less|vue|svelte)$/.test(filePath)) continue;
          const source =
            typeof fileNode.metadata?.source === 'string' ? fileNode.metadata.source : '';
          if (!source) continue;
          designViolations.push(...designAdapter.checkAll(source, filePath));
        }
      }
    }

    // Merge design violations into the result when present
    if (result.ok && designViolations.length > 0) {
      const merged = {
        ...result.value,
        designViolations,
      };
      return resultToMcpResponse({ ok: true, value: merged });
    }

    return resultToMcpResponse(result);
  } catch (error) {
    return {
      content: [
        {
          type: 'text' as const,
          text: `Error: ${error instanceof Error ? error.message : String(error)}`,
        },
      ],
      isError: true,
    };
  }
}
