#!/usr/bin/env node
/**
 * DSS Complexity Monitor Hook
 * Tracks code complexity metrics and warns on high-complexity code.
 * Written from scratch for DSS.
 */

const fs = require('fs');
const path = require('path');

// Configuration
const DEFAULT_CONFIG = {
  complexity_monitor: {
    enabled: true,
    max_function_lines: 50,
    max_component_lines: 200,
    max_props: 10,
    max_nesting_depth: 4,
    warn_only: true
  }
};

function loadConfig() {
  const configPath = path.join(process.env.HOME || '', '.dss', 'hooks-config.json');
  try {
    if (fs.existsSync(configPath)) {
      const userConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
      return { ...DEFAULT_CONFIG, ...userConfig };
    }
  } catch (e) {
    // Use defaults
  }
  return DEFAULT_CONFIG;
}

function countLines(content) {
  return content.split('\n').length;
}

function countProps(content) {
  // Count props in interface/type definition
  const propsMatch = content.match(/(?:interface|type)\s+\w*Props[^{]*\{([^}]+)\}/);
  if (propsMatch) {
    const propsContent = propsMatch[1];
    // Count semicolons or newlines with property definitions
    const props = propsContent.split(/[;\n]/).filter(line => {
      const trimmed = line.trim();
      return trimmed && !trimmed.startsWith('//') && trimmed.includes(':');
    });
    return props.length;
  }
  return 0;
}

function countNestingDepth(content) {
  let maxDepth = 0;
  let currentDepth = 0;
  
  for (const char of content) {
    if (char === '{' || char === '(') {
      currentDepth++;
      maxDepth = Math.max(maxDepth, currentDepth);
    } else if (char === '}' || char === ')') {
      currentDepth = Math.max(0, currentDepth - 1);
    }
  }
  
  return maxDepth;
}

function countFunctions(content) {
  const patterns = [
    /function\s+\w+\s*\([^)]*\)\s*\{/g,
    /const\s+\w+\s*=\s*(?:async\s*)?\([^)]*\)\s*=>/g,
    /const\s+\w+\s*=\s*(?:async\s*)?function/g
  ];
  
  let count = 0;
  for (const pattern of patterns) {
    const matches = content.match(pattern);
    if (matches) count += matches.length;
  }
  return count;
}

function analyzeComplexity(content, filePath, config) {
  const issues = [];
  const monitorConfig = config.complexity_monitor || {};
  const ext = path.extname(filePath).toLowerCase();
  
  // Only analyze JS/TS files
  if (!['.js', '.jsx', '.ts', '.tsx'].includes(ext)) {
    return issues;
  }
  
  const lines = countLines(content);
  const props = countProps(content);
  const nesting = countNestingDepth(content);
  const functions = countFunctions(content);
  
  // Check component size (for tsx/jsx files)
  if (['.tsx', '.jsx'].includes(ext)) {
    if (lines > monitorConfig.max_component_lines) {
      issues.push({
        type: 'component_size',
        severity: 'medium',
        message: `Component has ${lines} lines (max: ${monitorConfig.max_component_lines})`,
        suggestion: 'Consider breaking into smaller components'
      });
    }
    
    if (props > monitorConfig.max_props) {
      issues.push({
        type: 'prop_count',
        severity: 'medium',
        message: `Component has ${props} props (max: ${monitorConfig.max_props})`,
        suggestion: 'Consider grouping related props or using composition'
      });
    }
  }
  
  // Check nesting depth
  if (nesting > monitorConfig.max_nesting_depth) {
    issues.push({
      type: 'nesting_depth',
      severity: 'high',
      message: `Nesting depth of ${nesting} (max: ${monitorConfig.max_nesting_depth})`,
      suggestion: 'Extract nested logic into separate functions'
    });
  }
  
  // Check function count (indicator of file doing too much)
  if (functions > 10) {
    issues.push({
      type: 'function_count',
      severity: 'low',
      message: `File contains ${functions} functions`,
      suggestion: 'Consider splitting into multiple modules'
    });
  }
  
  return issues;
}

function formatOutput(issues, filePath) {
  if (issues.length === 0) return '';
  
  const severityIcons = {
    high: '[HIGH]',
    medium: '[MED]',
    low: '[LOW]'
  };
  
  const lines = [`\n=== DSS Complexity Monitor: ${filePath} ===\n`];
  
  for (const issue of issues) {
    const icon = severityIcons[issue.severity] || '[?]';
    lines.push(`${icon} ${issue.message}`);
    lines.push(`    Suggestion: ${issue.suggestion}\n`);
  }
  
  lines.push('='.repeat(50));
  return lines.join('\n');
}

async function main() {
  const config = loadConfig();
  
  if (!config.complexity_monitor?.enabled) {
    process.exit(0);
  }
  
  // Read input from stdin
  let inputData;
  try {
    const chunks = [];
    for await (const chunk of process.stdin) {
      chunks.push(chunk);
    }
    inputData = JSON.parse(Buffer.concat(chunks).toString());
  } catch (e) {
    process.exit(0);
  }
  
  const toolName = inputData.tool_name || '';
  const toolInput = inputData.tool_input || {};
  
  if (!['Edit', 'Write'].includes(toolName)) {
    process.exit(0);
  }
  
  const filePath = toolInput.file_path || '';
  let content = '';
  
  if (toolName === 'Write') {
    content = toolInput.content || '';
  } else if (toolName === 'Edit') {
    content = toolInput.new_string || '';
  }
  
  if (!content || !filePath) {
    process.exit(0);
  }
  
  const issues = analyzeComplexity(content, filePath, config);
  
  if (issues.length > 0) {
    const output = formatOutput(issues, filePath);
    console.error(output);
  }
  
  process.exit(0);
}

main().catch(() => process.exit(0));
