import { JSONSchema7 } from 'json-schema';
import { randomUUID } from 'crypto';
import { createTool, createSuccessResult, createErrorResult } from '../../core/tool-framework.js';
import { ToolRegistration, RequestContext } from '../../core/types.js';

/**
 * Development Module Tools - 12-Factor MCP Implementation
 * 
 * Implements Test-Driven Development (TDD) enforcement with:
 * - Feature-based development workflow
 * - Test-first enforcement
 * - Red-Green-Refactor cycle tracking
 * - Test coverage monitoring
 */

// Input type interfaces
interface CreateFeatureInput {
  name: string;
  description?: string;
  testCases?: Array<{
    name: string;
    description?: string;
    type?: 'unit' | 'integration' | 'e2e';
    expectedBehavior: string;
  }>;
}

interface WriteTestInput {
  featureId: string;
  name: string;
  description?: string;
  type?: 'unit' | 'integration' | 'e2e';
  expectedBehavior: string;
}

interface StartTDDSessionInput {
  featureId: string;
}

interface RunTestsInput {
  featureId: string;
  testResults: Array<{
    testId: string;
    status: 'passing' | 'failing' | 'skipped';
    actualBehavior?: string;
    errorMessage?: string;
  }>;
}

interface CheckTDDStatusInput {
  featureId?: string;
  sessionId?: string;
}

interface UpdateTDDConfigInput {
  enforceTestFirst?: boolean;
  minimumTestCoverage?: number;
  requireTestsBeforeImplementation?: boolean;
  autoGenerateTestTemplates?: boolean;
}

/**
 * Get or create default TDD configuration
 */
async function ensureTDDConfig(context: RequestContext): Promise<void> {
  const existingConfig = await context.db.get(
    'SELECT * FROM development_tdd_config WHERE project_id = ?',
    [context.projectId || 'default']
  );

  if (!existingConfig.success || !existingConfig.data) {
    await context.db.run(
      `INSERT INTO development_tdd_config 
       (project_id, enforce_test_first, minimum_test_coverage, require_tests_before_implementation, auto_generate_test_templates) 
       VALUES (?, ?, ?, ?, ?)`,
      [context.projectId || 'default', true, 80.0, true, true]
    );
  }
}

/**
 * Create a new feature for TDD development
 */
const createFeatureTool = createTool<CreateFeatureInput, any>({
  name: 'create_feature',
  description: 'Create a new feature for Test-Driven Development',
  category: 'development',
  inputSchema: {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        description: 'Feature name',
        minLength: 1,
        maxLength: 200
      },
      description: {
        type: 'string',
        description: 'Feature description',
        maxLength: 1000
      },
      testCases: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            name: {
              type: 'string',
              description: 'Test case name',
              minLength: 1,
              maxLength: 200
            },
            description: {
              type: 'string',
              description: 'Test case description',
              maxLength: 500
            },
            type: {
              type: 'string',
              enum: ['unit', 'integration', 'e2e'],
              default: 'unit',
              description: 'Type of test'
            },
            expectedBehavior: {
              type: 'string',
              description: 'Expected behavior',
              minLength: 1,
              maxLength: 1000
            }
          },
          required: ['name', 'expectedBehavior'],
          additionalProperties: false
        },
        description: 'Initial test cases for the feature',
        maxItems: 50
      }
    },
    required: ['name'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: CreateFeatureInput, context: RequestContext) {
    try {
      // Ensure TDD config exists
      await ensureTDDConfig(context);

      // Check TDD configuration
      const configResult = await context.db.get(
        'SELECT * FROM development_tdd_config WHERE project_id = ?',
        [context.projectId || 'default']
      );

      const config = configResult.data || {};

      // Check for duplicate feature names
      const existingFeature = await context.db.get(
        'SELECT id FROM development_features WHERE name = ? AND project_id = ?',
        [input.name, context.projectId || 'default']
      );

      if (existingFeature.success && existingFeature.data) {
        return createErrorResult({
          code: 'DUPLICATE_RESOURCE',
          message: 'A feature with this name already exists',
          category: 'validation'
        });
      }

      const featureId = randomUUID();
      const now = Date.now();

      // Create feature
      const result = await context.db.run(
        `INSERT INTO development_features 
         (id, project_id, name, description, status, test_coverage, created_at, updated_at) 
         VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          featureId,
          context.projectId || 'default',
          input.name,
          input.description || '',
          'planning',
          0.0,
          now,
          now
        ]
      );

      if (!result.success) {
        return createErrorResult({
          code: 'DATABASE_ERROR',
          message: 'Failed to create feature',
          details: { error: result.error },
          category: 'system'
        });
      }

      // Create initial test cases if provided
      const createdTests = [];
      if (input.testCases && input.testCases.length > 0) {
        for (const testCase of input.testCases) {
          const testId = randomUUID();
          
          await context.db.run(
            `INSERT INTO development_test_cases 
             (id, feature_id, project_id, name, description, type, status, expected_behavior, 
              created_at, updated_at) 
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [
              testId,
              featureId,
              context.projectId || 'default',
              testCase.name,
              testCase.description || '',
              testCase.type || 'unit',
              'pending',
              testCase.expectedBehavior,
              now,
              now
            ]
          );

          createdTests.push({
            id: testId,
            name: testCase.name,
            type: testCase.type || 'unit',
            status: 'pending'
          });
        }
      }

      return createSuccessResult({
        feature: {
          id: featureId,
          name: input.name,
          description: input.description || '',
          status: 'planning',
          testCoverage: 0,
          testCases: createdTests,
          createdAt: new Date(now).toISOString()
        },
        message: `Feature "${input.name}" created successfully`,
        tddGuidance: config.enforce_test_first 
          ? 'Remember: Write failing tests before implementing the feature (Red phase)'
          : 'TDD enforcement is disabled',
        nextSteps: [
          createdTests.length > 0 
            ? `Write implementations for ${createdTests.length} test cases`
            : 'Create test cases for this feature',
          'Start a TDD session to begin development',
          'Follow the Red-Green-Refactor cycle'
        ]
      });

    } catch (error) {
      return createErrorResult({
        code: 'EXECUTION_ERROR',
        message: `Failed to create feature: ${error instanceof Error ? error.message : 'Unknown error'}`,
        category: 'execution'
      });
    }
  }
});

/**
 * Write a test case for a feature
 */
const writeTestTool = createTool<WriteTestInput, any>({
  name: 'write_test',
  description: 'Write a test case for a feature (enforces test-first approach)',
  category: 'development',
  inputSchema: {
    type: 'object',
    properties: {
      featureId: {
        type: 'string',
        description: 'Feature ID',
        pattern: '^[a-zA-Z0-9-]+$'
      },
      name: {
        type: 'string',
        description: 'Test case name',
        minLength: 1,
        maxLength: 200
      },
      description: {
        type: 'string',
        description: 'Test case description',
        maxLength: 500
      },
      type: {
        type: 'string',
        enum: ['unit', 'integration', 'e2e'],
        default: 'unit',
        description: 'Type of test'
      },
      expectedBehavior: {
        type: 'string',
        description: 'Expected behavior',
        minLength: 1,
        maxLength: 1000
      }
    },
    required: ['featureId', 'name', 'expectedBehavior'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: WriteTestInput, context: RequestContext) {
    try {
      // Verify feature exists
      const featureResult = await context.db.get(
        'SELECT * FROM development_features WHERE id = ? AND project_id = ?',
        [input.featureId, context.projectId || 'default']
      );

      if (!featureResult.success || !featureResult.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: 'Feature not found',
          category: 'validation'
        });
      }

      const feature = featureResult.data;

      // Check TDD configuration
      const configResult = await context.db.get(
        'SELECT * FROM development_tdd_config WHERE project_id = ?',
        [context.projectId || 'default']
      );

      const config = configResult.data || {};

      // Enforce test-first if enabled
      if (config.enforce_test_first && feature.status === 'implementing') {
        return createErrorResult({
          code: 'TDD_VIOLATION',
          message: 'Cannot add tests during implementation phase. Complete current implementation first.',
          details: {
            currentStatus: feature.status,
            enforceTestFirst: true
          },
          category: 'validation'
        });
      }

      const testId = randomUUID();
      const now = Date.now();

      // Create test case
      const result = await context.db.run(
        `INSERT INTO development_test_cases 
         (id, feature_id, project_id, name, description, type, status, expected_behavior, 
          created_at, updated_at) 
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          testId,
          input.featureId,
          context.projectId || 'default',
          input.name,
          input.description || '',
          input.type || 'unit',
          'pending',
          input.expectedBehavior,
          now,
          now
        ]
      );

      if (!result.success) {
        return createErrorResult({
          code: 'DATABASE_ERROR',
          message: 'Failed to create test case',
          details: { error: result.error },
          category: 'system'
        });
      }

      // Update feature status if needed
      if (feature.status === 'planning') {
        await context.db.run(
          'UPDATE development_features SET status = ?, updated_at = ? WHERE id = ?',
          ['testing', now, input.featureId]
        );
      }

      // Get total test count
      const testCountResult = await context.db.get(
        'SELECT COUNT(*) as count FROM development_test_cases WHERE feature_id = ?',
        [input.featureId]
      );

      return createSuccessResult({
        test: {
          id: testId,
          name: input.name,
          type: input.type || 'unit',
          status: 'pending',
          expectedBehavior: input.expectedBehavior,
          createdAt: new Date(now).toISOString()
        },
        feature: {
          id: feature.id,
          name: feature.name,
          status: feature.status === 'planning' ? 'testing' : feature.status,
          totalTests: testCountResult.data?.count || 1
        },
        message: `Test case "${input.name}" created successfully`,
        tddPhase: 'Red - Write failing tests',
        nextSteps: [
          'Run the test to ensure it fails',
          'Write the minimum code to make it pass',
          'Refactor while keeping tests green'
        ]
      });

    } catch (error) {
      return createErrorResult({
        code: 'EXECUTION_ERROR',
        message: `Failed to write test: ${error instanceof Error ? error.message : 'Unknown error'}`,
        category: 'execution'
      });
    }
  }
});

/**
 * Start a TDD session for a feature
 */
const startTDDSessionTool = createTool<StartTDDSessionInput, any>({
  name: 'start_tdd_session',
  description: 'Start a Test-Driven Development session for a feature',
  category: 'development',
  inputSchema: {
    type: 'object',
    properties: {
      featureId: {
        type: 'string',
        description: 'Feature ID to start TDD session for',
        pattern: '^[a-zA-Z0-9-]+$'
      }
    },
    required: ['featureId'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: StartTDDSessionInput, context: RequestContext) {
    try {
      // Verify feature exists and get its tests
      const featureResult = await context.db.get(
        'SELECT * FROM development_features WHERE id = ? AND project_id = ?',
        [input.featureId, context.projectId || 'default']
      );

      if (!featureResult.success || !featureResult.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: 'Feature not found',
          category: 'validation'
        });
      }

      const feature = featureResult.data;

      // Check for existing active session
      const existingSession = await context.db.get(
        'SELECT * FROM development_tdd_sessions WHERE feature_id = ? AND completed_at IS NULL',
        [input.featureId]
      );

      if (existingSession.success && existingSession.data) {
        return createErrorResult({
          code: 'INVALID_STATE',
          message: 'A TDD session is already active for this feature',
          details: { sessionId: existingSession.data.id },
          category: 'validation'
        });
      }

      // Get test statistics
      const testStatsResult = await context.db.get(
        `SELECT 
           COUNT(*) as total,
           COUNT(CASE WHEN status = 'passing' THEN 1 END) as passing,
           COUNT(CASE WHEN status = 'failing' THEN 1 END) as failing,
           COUNT(CASE WHEN status = 'pending' THEN 1 END) as pending
         FROM development_test_cases 
         WHERE feature_id = ?`,
        [input.featureId]
      );

      const testStats = testStatsResult.data || { total: 0, passing: 0, failing: 0, pending: 0 };

      // Check TDD config
      const configResult = await context.db.get(
        'SELECT * FROM development_tdd_config WHERE project_id = ?',
        [context.projectId || 'default']
      );

      const config = configResult.data || {};

      // Enforce test requirements if enabled
      if (config.require_tests_before_implementation && testStats.total === 0) {
        return createErrorResult({
          code: 'TDD_VIOLATION',
          message: 'Cannot start TDD session without any test cases',
          details: {
            requireTestsBeforeImplementation: true,
            totalTests: 0
          },
          category: 'validation'
        });
      }

      const sessionId = randomUUID();
      const now = Date.now();

      // Determine initial phase based on test status
      let initialPhase = 'red';
      if (testStats.total > 0 && testStats.failing === 0 && testStats.pending === 0) {
        initialPhase = 'refactor'; // All tests passing
      } else if (testStats.passing > 0 && (testStats.failing > 0 || testStats.pending > 0)) {
        initialPhase = 'green'; // Some tests need work
      }

      // Create TDD session
      const result = await context.db.run(
        `INSERT INTO development_tdd_sessions 
         (id, feature_id, project_id, current_phase, started_at, created_at, updated_at) 
         VALUES (?, ?, ?, ?, ?, ?, ?)`,
        [
          sessionId,
          input.featureId,
          context.projectId || 'default',
          initialPhase,
          now,
          now,
          now
        ]
      );

      if (!result.success) {
        return createErrorResult({
          code: 'DATABASE_ERROR',
          message: 'Failed to create TDD session',
          details: { error: result.error },
          category: 'system'
        });
      }

      // Create initial phase history entry
      await context.db.run(
        `INSERT INTO development_tdd_phase_history 
         (id, session_id, project_id, phase, started_at) 
         VALUES (?, ?, ?, ?, ?)`,
        [
          randomUUID(),
          sessionId,
          context.projectId || 'default',
          initialPhase,
          now
        ]
      );

      // Update feature status
      await context.db.run(
        'UPDATE development_features SET status = ?, updated_at = ? WHERE id = ?',
        [initialPhase === 'red' ? 'testing' : 'implementing', now, input.featureId]
      );

      const phaseGuidance = {
        red: 'Write failing tests that define the desired behavior',
        green: 'Write the minimum code necessary to make tests pass',
        refactor: 'Improve code quality while keeping all tests passing'
      };

      return createSuccessResult({
        session: {
          id: sessionId,
          featureId: input.featureId,
          currentPhase: initialPhase,
          startedAt: new Date(now).toISOString()
        },
        feature: {
          id: feature.id,
          name: feature.name,
          status: initialPhase === 'red' ? 'testing' : 'implementing'
        },
        testStatistics: testStats,
        message: `TDD session started in ${initialPhase.toUpperCase()} phase`,
        phaseGuidance: phaseGuidance[initialPhase as keyof typeof phaseGuidance],
        nextSteps: initialPhase === 'red' 
          ? ['Write failing tests for the feature', 'Run tests to confirm they fail', 'Move to GREEN phase']
          : initialPhase === 'green'
          ? ['Implement code to make tests pass', 'Run tests frequently', 'Use minimal implementation']
          : ['Refactor for clarity and maintainability', 'Keep running tests', 'Look for code smells']
      });

    } catch (error) {
      return createErrorResult({
        code: 'EXECUTION_ERROR',
        message: `Failed to start TDD session: ${error instanceof Error ? error.message : 'Unknown error'}`,
        category: 'execution'
      });
    }
  }
});

/**
 * Run tests for a feature
 */
const runTestsTool = createTool<RunTestsInput, any>({
  name: 'run_tests',
  description: 'Record test execution results for a feature',
  category: 'development',
  inputSchema: {
    type: 'object',
    properties: {
      featureId: {
        type: 'string',
        description: 'Feature ID',
        pattern: '^[a-zA-Z0-9-]+$'
      },
      testResults: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            testId: {
              type: 'string',
              description: 'Test case ID',
              pattern: '^[a-zA-Z0-9-]+$'
            },
            status: {
              type: 'string',
              enum: ['passing', 'failing', 'skipped'],
              description: 'Test execution status'
            },
            actualBehavior: {
              type: 'string',
              description: 'Actual behavior observed',
              maxLength: 1000
            },
            errorMessage: {
              type: 'string',
              description: 'Error message if test failed',
              maxLength: 2000
            }
          },
          required: ['testId', 'status'],
          additionalProperties: false
        },
        description: 'Test execution results',
        minItems: 1,
        maxItems: 100
      }
    },
    required: ['featureId', 'testResults'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: RunTestsInput, context: RequestContext) {
    try {
      // Verify feature exists
      const featureResult = await context.db.get(
        'SELECT * FROM development_features WHERE id = ? AND project_id = ?',
        [input.featureId, context.projectId || 'default']
      );

      if (!featureResult.success || !featureResult.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: 'Feature not found',
          category: 'validation'
        });
      }

      const feature = featureResult.data;
      const now = Date.now();

      // Update test results
      let passing = 0;
      let failing = 0;
      let skipped = 0;

      for (const result of input.testResults) {
        // Verify test belongs to feature
        const testCheck = await context.db.get(
          'SELECT id FROM development_test_cases WHERE id = ? AND feature_id = ?',
          [result.testId, input.featureId]
        );

        if (!testCheck.success || !testCheck.data) {
          continue; // Skip invalid test IDs
        }

        await context.db.run(
          `UPDATE development_test_cases 
           SET status = ?, actual_behavior = ?, error_message = ?, updated_at = ? 
           WHERE id = ?`,
          [
            result.status,
            result.actualBehavior || null,
            result.errorMessage || null,
            now,
            result.testId
          ]
        );

        if (result.status === 'passing') passing++;
        else if (result.status === 'failing') failing++;
        else if (result.status === 'skipped') skipped++;
      }

      // Calculate test coverage
      const totalTestsResult = await context.db.get(
        'SELECT COUNT(*) as total FROM development_test_cases WHERE feature_id = ?',
        [input.featureId]
      );

      const totalTests = totalTestsResult.data?.total || 0;
      const testCoverage = totalTests > 0 ? (passing / totalTests) * 100 : 0;

      // Update feature test coverage
      await context.db.run(
        'UPDATE development_features SET test_coverage = ?, updated_at = ? WHERE id = ?',
        [testCoverage, now, input.featureId]
      );

      // Check for active TDD session
      const sessionResult = await context.db.get(
        'SELECT * FROM development_tdd_sessions WHERE feature_id = ? AND completed_at IS NULL',
        [input.featureId]
      );

      let phaseTransition = null;
      if (sessionResult.success && sessionResult.data) {
        const session = sessionResult.data;
        const currentPhase = session.current_phase;
        let newPhase = currentPhase;

        // Determine phase transition based on test results
        if (currentPhase === 'red' && failing === 0 && passing > 0) {
          // All tests passing, move to refactor
          newPhase = 'refactor';
        } else if (currentPhase === 'green' && failing > 0) {
          // Tests failing during implementation, back to red
          newPhase = 'red';
        } else if (currentPhase === 'refactor' && failing > 0) {
          // Tests broken during refactoring, back to green
          newPhase = 'green';
        }

        if (newPhase !== currentPhase) {
          // Update session phase
          await context.db.run(
            'UPDATE development_tdd_sessions SET current_phase = ?, updated_at = ? WHERE id = ?',
            [newPhase, now, session.id]
          );

          // Complete previous phase in history
          await context.db.run(
            'UPDATE development_tdd_phase_history SET completed_at = ? WHERE session_id = ? AND completed_at IS NULL',
            [now, session.id]
          );

          // Start new phase in history
          await context.db.run(
            `INSERT INTO development_tdd_phase_history 
             (id, session_id, project_id, phase, started_at) 
             VALUES (?, ?, ?, ?, ?)`,
            [randomUUID(), session.id, context.projectId || 'default', newPhase, now]
          );

          phaseTransition = { from: currentPhase, to: newPhase };
        }
      }

      // Check TDD config for coverage requirements
      const configResult = await context.db.get(
        'SELECT * FROM development_tdd_config WHERE project_id = ?',
        [context.projectId || 'default']
      );

      const config = configResult.data || {};
      const meetsMinimumCoverage = testCoverage >= (config.minimum_test_coverage || 80);

      return createSuccessResult({
        testResults: {
          total: totalTests,
          passing,
          failing,
          skipped,
          coverage: Math.round(testCoverage * 100) / 100
        },
        feature: {
          id: feature.id,
          name: feature.name,
          testCoverage: Math.round(testCoverage * 100) / 100
        },
        phaseTransition,
        meetsMinimumCoverage,
        message: failing > 0 
          ? `${failing} test(s) failing - fix them to proceed`
          : `All tests passing! Coverage: ${Math.round(testCoverage)}%`,
        nextSteps: failing > 0
          ? ['Fix failing tests', 'Review error messages', 'Update implementation']
          : phaseTransition?.to === 'refactor'
          ? ['Refactor code for clarity', 'Eliminate duplication', 'Improve design']
          : ['Continue with implementation', 'Add more test cases', 'Check edge cases']
      });

    } catch (error) {
      return createErrorResult({
        code: 'EXECUTION_ERROR',
        message: `Failed to run tests: ${error instanceof Error ? error.message : 'Unknown error'}`,
        category: 'execution'
      });
    }
  }
});

/**
 * Check TDD status
 */
const checkTDDStatusTool = createTool<CheckTDDStatusInput, any>({
  name: 'check_tdd_status',
  description: 'Check the status of TDD sessions and features',
  category: 'development',
  readOnly: true,
  inputSchema: {
    type: 'object',
    properties: {
      featureId: {
        type: 'string',
        description: 'Feature ID to check status for',
        pattern: '^[a-zA-Z0-9-]+$'
      },
      sessionId: {
        type: 'string',
        description: 'Session ID to check status for',
        pattern: '^[a-zA-Z0-9-]+$'
      }
    },
    required: [],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: CheckTDDStatusInput, context: RequestContext) {
    try {
      if (input.sessionId) {
        // Get specific session status
        const sessionResult = await context.db.get(
          `SELECT s.*, f.name as feature_name, f.test_coverage 
           FROM development_tdd_sessions s 
           JOIN development_features f ON s.feature_id = f.id 
           WHERE s.id = ? AND s.project_id = ?`,
          [input.sessionId, context.projectId || 'default']
        );

        if (!sessionResult.success || !sessionResult.data) {
          return createErrorResult({
            code: 'RESOURCE_NOT_FOUND',
            message: 'Session not found',
            category: 'validation'
          });
        }

        const session = sessionResult.data;

        // Get phase history
        const historyResult = await context.db.query(
          'SELECT * FROM development_tdd_phase_history WHERE session_id = ? ORDER BY started_at',
          [input.sessionId]
        );

        const phaseHistory = (historyResult.data || []).map((ph: any) => ({
          phase: ph.phase,
          startedAt: new Date(ph.started_at).toISOString(),
          completedAt: ph.completed_at ? new Date(ph.completed_at).toISOString() : null,
          duration: ph.completed_at ? ph.completed_at - ph.started_at : null
        }));

        return createSuccessResult({
          session: {
            id: session.id,
            featureName: session.feature_name,
            currentPhase: session.current_phase,
            startedAt: new Date(session.started_at).toISOString(),
            completedAt: session.completed_at ? new Date(session.completed_at).toISOString() : null,
            testCoverage: session.test_coverage,
            phaseHistory
          }
        });

      } else if (input.featureId) {
        // Get feature status with tests
        const featureResult = await context.db.get(
          'SELECT * FROM development_features WHERE id = ? AND project_id = ?',
          [input.featureId, context.projectId || 'default']
        );

        if (!featureResult.success || !featureResult.data) {
          return createErrorResult({
            code: 'RESOURCE_NOT_FOUND',
            message: 'Feature not found',
            category: 'validation'
          });
        }

        const feature = featureResult.data;

        // Get test statistics
        const testStatsResult = await context.db.get(
          `SELECT 
             COUNT(*) as total,
             COUNT(CASE WHEN status = 'passing' THEN 1 END) as passing,
             COUNT(CASE WHEN status = 'failing' THEN 1 END) as failing,
             COUNT(CASE WHEN status = 'pending' THEN 1 END) as pending
           FROM development_test_cases 
           WHERE feature_id = ?`,
          [input.featureId]
        );

        // Get active session if any
        const sessionResult = await context.db.get(
          'SELECT * FROM development_tdd_sessions WHERE feature_id = ? AND completed_at IS NULL',
          [input.featureId]
        );

        return createSuccessResult({
          feature: {
            id: feature.id,
            name: feature.name,
            status: feature.status,
            testCoverage: feature.test_coverage,
            createdAt: new Date(feature.created_at).toISOString()
          },
          tests: testStatsResult.data || { total: 0, passing: 0, failing: 0, pending: 0 },
          activeSession: sessionResult.data ? {
            id: sessionResult.data.id,
            currentPhase: sessionResult.data.current_phase,
            startedAt: new Date(sessionResult.data.started_at).toISOString()
          } : null
        });

      } else {
        // Get overall TDD status
        const featuresResult = await context.db.query(
          'SELECT * FROM development_features WHERE project_id = ? ORDER BY created_at DESC LIMIT 10',
          [context.projectId || 'default']
        );

        const activeSessions = await context.db.query(
          `SELECT s.*, f.name as feature_name 
           FROM development_tdd_sessions s 
           JOIN development_features f ON s.feature_id = f.id 
           WHERE s.project_id = ? AND s.completed_at IS NULL`,
          [context.projectId || 'default']
        );

        const configResult = await context.db.get(
          'SELECT * FROM development_tdd_config WHERE project_id = ?',
          [context.projectId || 'default']
        );

        return createSuccessResult({
          recentFeatures: (featuresResult.data || []).map((f: any) => ({
            id: f.id,
            name: f.name,
            status: f.status,
            testCoverage: f.test_coverage
          })),
          activeSessions: (activeSessions.data || []).map((s: any) => ({
            id: s.id,
            featureName: s.feature_name,
            currentPhase: s.current_phase,
            startedAt: new Date(s.started_at).toISOString()
          })),
          tddConfig: configResult.data || {
            enforceTestFirst: true,
            minimumTestCoverage: 80,
            requireTestsBeforeImplementation: true,
            autoGenerateTestTemplates: true
          }
        });
      }

    } catch (error) {
      return createErrorResult({
        code: 'EXECUTION_ERROR',
        message: `Failed to check TDD status: ${error instanceof Error ? error.message : 'Unknown error'}`,
        category: 'execution'
      });
    }
  }
});

/**
 * Show or update TDD enforcement configuration
 */
const enforceTDDTool = createTool<UpdateTDDConfigInput, any>({
  name: 'enforce_tdd',
  description: 'Show or update Test-Driven Development enforcement configuration',
  category: 'development',
  inputSchema: {
    type: 'object',
    properties: {
      enforceTestFirst: {
        type: 'boolean',
        description: 'Enforce writing tests before implementation'
      },
      minimumTestCoverage: {
        type: 'number',
        description: 'Minimum required test coverage percentage',
        minimum: 0,
        maximum: 100
      },
      requireTestsBeforeImplementation: {
        type: 'boolean',
        description: 'Require at least one test before allowing implementation'
      },
      autoGenerateTestTemplates: {
        type: 'boolean',
        description: 'Automatically generate test templates for new features'
      }
    },
    required: [],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: UpdateTDDConfigInput, context: RequestContext) {
    try {
      // Ensure config exists
      await ensureTDDConfig(context);

      // If no input provided, just return current config
      if (Object.keys(input).length === 0) {
        const configResult = await context.db.get(
          'SELECT * FROM development_tdd_config WHERE project_id = ?',
          [context.projectId || 'default']
        );

        const config = configResult.data || {};

        return createSuccessResult({
          config: {
            enforceTestFirst: config.enforce_test_first,
            minimumTestCoverage: config.minimum_test_coverage,
            requireTestsBeforeImplementation: config.require_tests_before_implementation,
            autoGenerateTestTemplates: config.auto_generate_test_templates
          },
          message: 'Current TDD enforcement configuration',
          description: {
            enforceTestFirst: 'Prevents adding tests during implementation phase',
            minimumTestCoverage: 'Required percentage of passing tests',
            requireTestsBeforeImplementation: 'Blocks implementation without tests',
            autoGenerateTestTemplates: 'Creates test stubs for new features'
          }
        });
      }

      // Update configuration
      const updates = [];
      const values = [];

      if (input.enforceTestFirst !== undefined) {
        updates.push('enforce_test_first = ?');
        values.push(input.enforceTestFirst);
      }

      if (input.minimumTestCoverage !== undefined) {
        updates.push('minimum_test_coverage = ?');
        values.push(input.minimumTestCoverage);
      }

      if (input.requireTestsBeforeImplementation !== undefined) {
        updates.push('require_tests_before_implementation = ?');
        values.push(input.requireTestsBeforeImplementation);
      }

      if (input.autoGenerateTestTemplates !== undefined) {
        updates.push('auto_generate_test_templates = ?');
        values.push(input.autoGenerateTestTemplates);
      }

      if (updates.length > 0) {
        updates.push('updated_at = ?');
        values.push(Date.now());
        values.push(context.projectId || 'default');

        await context.db.run(
          `UPDATE development_tdd_config SET ${updates.join(', ')} WHERE project_id = ?`,
          values
        );
      }

      // Get updated config
      const updatedResult = await context.db.get(
        'SELECT * FROM development_tdd_config WHERE project_id = ?',
        [context.projectId || 'default']
      );

      const updatedConfig = updatedResult.data || {};

      return createSuccessResult({
        config: {
          enforceTestFirst: updatedConfig.enforce_test_first,
          minimumTestCoverage: updatedConfig.minimum_test_coverage,
          requireTestsBeforeImplementation: updatedConfig.require_tests_before_implementation,
          autoGenerateTestTemplates: updatedConfig.auto_generate_test_templates
        },
        message: 'TDD configuration updated successfully',
        changes: updates.length > 0 ? updates.map(u => u.split(' = ')[0]) : ['No changes']
      });

    } catch (error) {
      return createErrorResult({
        code: 'EXECUTION_ERROR',
        message: `Failed to update TDD config: ${error instanceof Error ? error.message : 'Unknown error'}`,
        category: 'execution'
      });
    }
  }
});

/**
 * Setup development tools
 */
export async function setupDevelopmentTools(): Promise<ToolRegistration> {
  return {
    module: 'development',
    tools: [
      createFeatureTool,
      writeTestTool,
      startTDDSessionTool,
      runTestsTool,
      checkTDDStatusTool,
      enforceTDDTool
    ]
  };
}