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';

/**
 * Product Requirements Tools - 12-Factor MCP Implementation
 * 
 * Implements Factor 2: Deterministic Execution with structured outputs
 * Implements Factor 3: Stateless Processes with RequestContext
 * Implements Factor 4: Structured Outputs for LLM consumption
 */

// Input type interfaces
interface CreateRequirementInput {
  name: string;
  type: 'functional' | 'non-functional' | 'business' | 'technical' | 'user-interface' | 'security' | 'performance';
  description: string;
  acceptanceCriteria?: string[];
  priority?: 'low' | 'medium' | 'high' | 'critical';
  status?: 'draft' | 'approved' | 'in_development' | 'implemented' | 'deprecated';
  repositories?: Array<{
    name: string;
    implementationStatus: 'not_started' | 'in_progress' | 'completed' | 'blocked';
    branch?: string;
    prUrl?: string;
    notes?: string;
  }>;
  relatedStories?: string[];
  tags?: string[];
  businessValue?: string;
  technicalNotes?: string;
  testCriteria?: string[];
  complianceRequirements?: string[];
  estimatedEffort?: string;
  targetRelease?: string;
  parentRequirementId?: string;
}

interface UpdateRequirementInput {
  id: string;
  name?: string;
  type?: 'functional' | 'non-functional' | 'business' | 'technical' | 'user-interface' | 'security' | 'performance';
  description?: string;
  acceptanceCriteria?: string[];
  priority?: 'low' | 'medium' | 'high' | 'critical';
  status?: 'draft' | 'approved' | 'in_development' | 'implemented' | 'deprecated';
  repositories?: Array<{
    name: string;
    implementationStatus: 'not_started' | 'in_progress' | 'completed' | 'blocked';
    branch?: string;
    prUrl?: string;
    notes?: string;
  }>;
  tags?: string[];
  businessValue?: string;
  technicalNotes?: string;
  testCriteria?: string[];
  complianceRequirements?: string[];
  estimatedEffort?: string;
  actualEffort?: string;
  targetRelease?: string;
  documentationLinks?: string[];
}

interface ListRequirementsInput {
  filterByType?: 'functional' | 'non-functional' | 'business' | 'technical' | 'user-interface' | 'security' | 'performance';
  filterByStatus?: 'draft' | 'approved' | 'in_development' | 'implemented' | 'deprecated';
  filterByPriority?: 'low' | 'medium' | 'high' | 'critical';
  filterByRepository?: string;
  filterByTag?: string;
  filterByParent?: string;
  hasStories?: boolean;
  implementationStatus?: 'not_started' | 'in_progress' | 'completed' | 'blocked';
}

interface SearchRequirementsInput {
  query: string;
  searchIn?: ('name' | 'description' | 'acceptance_criteria' | 'tags')[];
  limit?: number;
  offset?: number;
}

interface LinkRequirementToStoryInput {
  requirementId: string;
  storyId: string;
  linkType?: 'implements' | 'relates_to' | 'depends_on';
  notes?: string;
}

interface UpdateImplementationStatusInput {
  requirementId: string;
  repositoryName: string;
  status: 'not_started' | 'in_progress' | 'completed' | 'blocked';
  branch?: string;
  prUrl?: string;
  notes?: string;
}

interface GenerateReportInput {
  format?: 'json' | 'markdown' | 'html';
  includeImplementationStatus?: boolean;
  groupBy?: 'type' | 'status' | 'priority';
  filterType?: 'functional' | 'non-functional' | 'business' | 'technical' | 'user-interface' | 'security' | 'performance';
  filterStatus?: 'draft' | 'approved' | 'in_development' | 'implemented' | 'deprecated';
  filterPriority?: 'low' | 'medium' | 'high' | 'critical';
}

/**
 * Create a new product requirement
 */
const createRequirementTool = createTool<CreateRequirementInput, any>({
  name: 'create_requirement',
  description: 'Create a new product requirement',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        description: 'Name of the requirement',
        minLength: 1,
        maxLength: 200
      },
      type: {
        type: 'string',
        enum: ['functional', 'non-functional', 'business', 'technical', 'user-interface', 'security', 'performance'],
        description: 'Type of requirement'
      },
      description: {
        type: 'string',
        description: 'Detailed description of the requirement',
        minLength: 1,
        maxLength: 5000
      },
      acceptanceCriteria: {
        type: 'array',
        items: { type: 'string', maxLength: 1000 },
        description: 'List of acceptance criteria',
        maxItems: 20
      },
      priority: {
        type: 'string',
        enum: ['low', 'medium', 'high', 'critical'],
        description: 'Priority level',
        default: 'medium'
      },
      status: {
        type: 'string',
        enum: ['draft', 'approved', 'in_development', 'implemented', 'deprecated'],
        description: 'Current status',
        default: 'draft'
      },
      repositories: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            name: { type: 'string', maxLength: 100 },
            implementationStatus: { 
              type: 'string',
              enum: ['not_started', 'in_progress', 'completed', 'blocked']
            },
            branch: { type: 'string', maxLength: 100 },
            prUrl: { type: 'string', maxLength: 500 },
            notes: { type: 'string', maxLength: 1000 }
          },
          required: ['name', 'implementationStatus'],
          additionalProperties: false
        },
        description: 'Repositories where this requirement is implemented',
        maxItems: 10
      },
      relatedStories: {
        type: 'array',
        items: { type: 'string' },
        description: 'IDs of related user stories',
        maxItems: 50
      },
      tags: {
        type: 'array',
        items: { type: 'string', maxLength: 50 },
        description: 'Tags for categorization',
        maxItems: 20
      },
      businessValue: {
        type: 'string',
        description: 'Business value statement',
        maxLength: 2000
      },
      technicalNotes: {
        type: 'string',
        description: 'Technical implementation notes',
        maxLength: 5000
      },
      testCriteria: {
        type: 'array',
        items: { type: 'string', maxLength: 1000 },
        description: 'Testing criteria',
        maxItems: 20
      },
      complianceRequirements: {
        type: 'array',
        items: { type: 'string', maxLength: 500 },
        description: 'Compliance and regulatory requirements',
        maxItems: 10
      },
      estimatedEffort: {
        type: 'string',
        description: 'Estimated effort (e.g., "2 weeks", "5 story points")',
        maxLength: 100
      },
      targetRelease: {
        type: 'string',
        description: 'Target release version',
        maxLength: 50
      },
      parentRequirementId: {
        type: 'string',
        description: 'ID of parent requirement for hierarchical organization',
        pattern: '^req-[a-f0-9-]+$'
      }
    },
    required: ['name', 'type', 'description'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: CreateRequirementInput, context: RequestContext) {
    try {
      const requirementId = `req-${randomUUID()}`;
      const now = Date.now();

      // Validate parent requirement if provided
      if (input.parentRequirementId) {
        const parentCheck = await context.db.get(
          'SELECT id FROM product_requirements WHERE id = ? AND project_id = ?',
          [input.parentRequirementId, context.projectId || 'default']
        );

        if (!parentCheck.success || !parentCheck.data) {
          return createErrorResult({
            code: 'VALIDATION_ERROR',
            message: 'Parent requirement not found',
            details: { parentRequirementId: input.parentRequirementId },
            category: 'validation'
          });
        }
      }

      // Insert requirement
      const result = await context.db.run(
        `INSERT INTO product_requirements 
         (id, project_id, name, type, description, acceptance_criteria, priority, status,
          related_stories, tags, created_at, updated_at, created_by, version,
          parent_requirement_id, business_value, technical_notes, test_criteria,
          compliance_requirements, estimated_effort, target_release) 
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          requirementId,
          context.projectId || 'default',
          input.name,
          input.type,
          input.description,
          JSON.stringify(input.acceptanceCriteria || []),
          input.priority || 'medium',
          input.status || 'draft',
          JSON.stringify(input.relatedStories || []),
          JSON.stringify(input.tags || []),
          now,
          now,
          context.userId || 'system',
          1,
          input.parentRequirementId || null,
          input.businessValue || null,
          input.technicalNotes || null,
          JSON.stringify(input.testCriteria || []),
          JSON.stringify(input.complianceRequirements || []),
          input.estimatedEffort || null,
          input.targetRelease || null
        ]
      );

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

      // Insert repositories if provided
      if (input.repositories && input.repositories.length > 0) {
        for (const repo of input.repositories) {
          const repoId = `repo-${randomUUID()}`;
          await context.db.run(
            `INSERT INTO requirement_repositories 
             (id, requirement_id, project_id, name, implementation_status, branch, pr_url, notes, created_at, updated_at)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [
              repoId,
              requirementId,
              context.projectId || 'default',
              repo.name,
              repo.implementationStatus,
              repo.branch || null,
              repo.prUrl || null,
              repo.notes || null,
              now,
              now
            ]
          );
        }
      }

      // Update parent requirement's child_requirement_ids if applicable
      if (input.parentRequirementId) {
        const parent = await context.db.get(
          'SELECT child_requirement_ids FROM product_requirements WHERE id = ?',
          [input.parentRequirementId]
        );
        
        if (parent.success && parent.data) {
          const childIds = JSON.parse(parent.data.child_requirement_ids || '[]');
          childIds.push(requirementId);
          
          await context.db.run(
            'UPDATE product_requirements SET child_requirement_ids = ?, updated_at = ? WHERE id = ?',
            [JSON.stringify(childIds), now, input.parentRequirementId]
          );
        }
      }

      return createSuccessResult({
        requirement: {
          id: requirementId,
          name: input.name,
          type: input.type,
          description: input.description,
          status: input.status || 'draft',
          priority: input.priority || 'medium',
          version: 1
        },
        message: `Created requirement "${input.name}" with ID ${requirementId}`,
        nextSteps: [
          'Add acceptance criteria if not already provided',
          'Link to user stories using link_requirement_to_story',
          'Update implementation status as development progresses',
          'Review and approve the requirement when ready'
        ]
      });

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

/**
 * List all product requirements with optional filtering
 */
const listRequirementsTool = createTool<ListRequirementsInput, any>({
  name: 'list_requirements',
  description: 'List all product requirements with optional filtering',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      filterByType: {
        type: 'string',
        enum: ['functional', 'non-functional', 'business', 'technical', 'user-interface', 'security', 'performance'],
        description: 'Filter by requirement type'
      },
      filterByStatus: {
        type: 'string',
        enum: ['draft', 'approved', 'in_development', 'implemented', 'deprecated'],
        description: 'Filter by status'
      },
      filterByPriority: {
        type: 'string',
        enum: ['low', 'medium', 'high', 'critical'],
        description: 'Filter by priority'
      },
      filterByRepository: {
        type: 'string',
        description: 'Filter by repository name',
        maxLength: 100
      },
      filterByTag: {
        type: 'string',
        description: 'Filter by tag',
        maxLength: 50
      },
      filterByParent: {
        type: 'string',
        description: 'Filter by parent requirement ID',
        pattern: '^req-[a-f0-9-]+$'
      },
      hasStories: {
        type: 'boolean',
        description: 'Filter requirements with/without related stories'
      },
      implementationStatus: {
        type: 'string',
        enum: ['not_started', 'in_progress', 'completed', 'blocked'],
        description: 'Filter by implementation status in any repository'
      }
    },
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: ListRequirementsInput, context: RequestContext) {
    try {
      let query = `
        SELECT DISTINCT r.*,
        (SELECT COUNT(*) FROM requirement_repositories WHERE requirement_id = r.id) as repo_count,
        (SELECT COUNT(*) FROM requirement_story_links WHERE requirement_id = r.id) as story_count
        FROM product_requirements r
        WHERE r.project_id = ?
      `;
      const params: any[] = [context.projectId || 'default'];

      // Apply filters
      if (input.filterByType) {
        query += ' AND r.type = ?';
        params.push(input.filterByType);
      }

      if (input.filterByStatus) {
        query += ' AND r.status = ?';
        params.push(input.filterByStatus);
      }

      if (input.filterByPriority) {
        query += ' AND r.priority = ?';
        params.push(input.filterByPriority);
      }

      if (input.filterByTag) {
        query += ' AND r.tags LIKE ?';
        params.push(`%"${input.filterByTag}"%`);
      }

      if (input.filterByParent !== undefined) {
        if (input.filterByParent === null) {
          query += ' AND r.parent_requirement_id IS NULL';
        } else {
          query += ' AND r.parent_requirement_id = ?';
          params.push(input.filterByParent);
        }
      }

      if (input.hasStories !== undefined) {
        if (input.hasStories) {
          query += ' AND EXISTS (SELECT 1 FROM requirement_story_links WHERE requirement_id = r.id)';
        } else {
          query += ' AND NOT EXISTS (SELECT 1 FROM requirement_story_links WHERE requirement_id = r.id)';
        }
      }

      if (input.filterByRepository || input.implementationStatus) {
        query += ' AND EXISTS (SELECT 1 FROM requirement_repositories rr WHERE rr.requirement_id = r.id';
        
        if (input.filterByRepository) {
          query += ' AND rr.name = ?';
          params.push(input.filterByRepository);
        }
        
        if (input.implementationStatus) {
          query += ' AND rr.implementation_status = ?';
          params.push(input.implementationStatus);
        }
        
        query += ')';
      }

      query += ' ORDER BY r.priority DESC, r.updated_at DESC';

      const requirements = await context.db.all(query, params);

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

      if (requirements.data.length === 0) {
        return createSuccessResult({
          requirements: [],
          totalCount: 0,
          message: 'No requirements found matching the criteria'
        });
      }

      // Get repository details for each requirement
      const requirementsWithRepos = await Promise.all(
        requirements.data.map(async (req: any) => {
          const repos = await context.db.all(
            'SELECT * FROM requirement_repositories WHERE requirement_id = ?',
            [req.id]
          );

          return {
            id: req.id,
            name: req.name,
            type: req.type,
            description: req.description,
            priority: req.priority,
            status: req.status,
            tags: JSON.parse(req.tags || '[]'),
            repositories: repos.success ? repos.data.map((r: any) => ({
              name: r.name,
              implementationStatus: r.implementation_status,
              branch: r.branch,
              prUrl: r.pr_url
            })) : [],
            storyCount: req.story_count,
            createdAt: new Date(req.created_at).toISOString(),
            updatedAt: new Date(req.updated_at).toISOString()
          };
        })
      );

      // Generate summary statistics
      const stats = {
        byType: {} as Record<string, number>,
        byStatus: {} as Record<string, number>,
        byPriority: {} as Record<string, number>
      };

      requirementsWithRepos.forEach(req => {
        stats.byType[req.type] = (stats.byType[req.type] || 0) + 1;
        stats.byStatus[req.status] = (stats.byStatus[req.status] || 0) + 1;
        stats.byPriority[req.priority] = (stats.byPriority[req.priority] || 0) + 1;
      });

      return createSuccessResult({
        requirements: requirementsWithRepos,
        totalCount: requirementsWithRepos.length,
        statistics: stats,
        message: `Found ${requirementsWithRepos.length} requirement(s)`
      });

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

/**
 * Get a specific product requirement by ID
 */
const getRequirementTool = createTool<{ id: string }, any>({
  name: 'get_requirement',
  description: 'Get a specific product requirement by ID',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      id: {
        type: 'string',
        description: 'Requirement ID',
        pattern: '^req-[a-f0-9-]+$'
      }
    },
    required: ['id'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: { id: string }, context: RequestContext) {
    try {
      const requirement = await context.db.get(
        'SELECT * FROM product_requirements WHERE id = ? AND project_id = ?',
        [input.id, context.projectId || 'default']
      );

      if (!requirement.success || !requirement.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: `Requirement ${input.id} not found`,
          details: { requirementId: input.id },
          category: 'validation'
        });
      }

      // Get repositories
      const repos = await context.db.all(
        'SELECT * FROM requirement_repositories WHERE requirement_id = ?',
        [input.id]
      );

      // Get story links
      const storyLinks = await context.db.all(
        'SELECT * FROM requirement_story_links WHERE requirement_id = ?',
        [input.id]
      );

      // Get child requirements if any
      let childRequirements = [];
      if (requirement.data.child_requirement_ids) {
        const childIds = JSON.parse(requirement.data.child_requirement_ids);
        if (childIds.length > 0) {
          const placeholders = childIds.map(() => '?').join(',');
          const children = await context.db.all(
            `SELECT id, name, type, status FROM product_requirements WHERE id IN (${placeholders})`,
            childIds
          );
          childRequirements = children.success ? children.data : [];
        }
      }

      const requirementData = {
        id: requirement.data.id,
        name: requirement.data.name,
        type: requirement.data.type,
        description: requirement.data.description,
        acceptanceCriteria: JSON.parse(requirement.data.acceptance_criteria || '[]'),
        priority: requirement.data.priority,
        status: requirement.data.status,
        repositories: repos.success ? repos.data.map((r: any) => ({
          name: r.name,
          implementationStatus: r.implementation_status,
          branch: r.branch,
          prUrl: r.pr_url,
          notes: r.notes
        })) : [],
        relatedStories: JSON.parse(requirement.data.related_stories || '[]'),
        storyLinks: storyLinks.success ? storyLinks.data.map((l: any) => ({
          storyId: l.story_id,
          linkType: l.link_type,
          notes: l.notes
        })) : [],
        tags: JSON.parse(requirement.data.tags || '[]'),
        createdAt: new Date(requirement.data.created_at).toISOString(),
        updatedAt: new Date(requirement.data.updated_at).toISOString(),
        createdBy: requirement.data.created_by,
        approvedBy: requirement.data.approved_by,
        approvedAt: requirement.data.approved_at ? new Date(requirement.data.approved_at).toISOString() : null,
        version: requirement.data.version,
        parentRequirementId: requirement.data.parent_requirement_id,
        childRequirements,
        dependencies: JSON.parse(requirement.data.dependencies || '[]'),
        businessValue: requirement.data.business_value,
        technicalNotes: requirement.data.technical_notes,
        testCriteria: JSON.parse(requirement.data.test_criteria || '[]'),
        complianceRequirements: JSON.parse(requirement.data.compliance_requirements || '[]'),
        estimatedEffort: requirement.data.estimated_effort,
        actualEffort: requirement.data.actual_effort,
        targetRelease: requirement.data.target_release,
        documentationLinks: JSON.parse(requirement.data.documentation_links || '[]')
      };

      return createSuccessResult({
        requirement: requirementData,
        message: `Retrieved requirement "${requirementData.name}"`
      });

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

/**
 * Update an existing product requirement
 */
const updateRequirementTool = createTool<UpdateRequirementInput, any>({
  name: 'update_requirement',
  description: 'Update an existing product requirement',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      id: {
        type: 'string',
        description: 'Requirement ID to update',
        pattern: '^req-[a-f0-9-]+$'
      },
      name: {
        type: 'string',
        description: 'Updated name',
        minLength: 1,
        maxLength: 200
      },
      type: {
        type: 'string',
        enum: ['functional', 'non-functional', 'business', 'technical', 'user-interface', 'security', 'performance'],
        description: 'Updated type'
      },
      description: {
        type: 'string',
        description: 'Updated description',
        minLength: 1,
        maxLength: 5000
      },
      acceptanceCriteria: {
        type: 'array',
        items: { type: 'string', maxLength: 1000 },
        description: 'Updated acceptance criteria',
        maxItems: 20
      },
      priority: {
        type: 'string',
        enum: ['low', 'medium', 'high', 'critical'],
        description: 'Updated priority'
      },
      status: {
        type: 'string',
        enum: ['draft', 'approved', 'in_development', 'implemented', 'deprecated'],
        description: 'Updated status'
      },
      repositories: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            name: { type: 'string', maxLength: 100 },
            implementationStatus: { 
              type: 'string',
              enum: ['not_started', 'in_progress', 'completed', 'blocked']
            },
            branch: { type: 'string', maxLength: 100 },
            prUrl: { type: 'string', maxLength: 500 },
            notes: { type: 'string', maxLength: 1000 }
          },
          required: ['name', 'implementationStatus'],
          additionalProperties: false
        },
        description: 'Updated repository information',
        maxItems: 10
      },
      tags: {
        type: 'array',
        items: { type: 'string', maxLength: 50 },
        description: 'Updated tags',
        maxItems: 20
      },
      businessValue: {
        type: 'string',
        description: 'Updated business value',
        maxLength: 2000
      },
      technicalNotes: {
        type: 'string',
        description: 'Updated technical notes',
        maxLength: 5000
      },
      testCriteria: {
        type: 'array',
        items: { type: 'string', maxLength: 1000 },
        description: 'Updated test criteria',
        maxItems: 20
      },
      complianceRequirements: {
        type: 'array',
        items: { type: 'string', maxLength: 500 },
        description: 'Updated compliance requirements',
        maxItems: 10
      },
      estimatedEffort: {
        type: 'string',
        description: 'Updated estimated effort',
        maxLength: 100
      },
      actualEffort: {
        type: 'string',
        description: 'Actual effort spent',
        maxLength: 100
      },
      targetRelease: {
        type: 'string',
        description: 'Updated target release',
        maxLength: 50
      },
      documentationLinks: {
        type: 'array',
        items: { type: 'string', maxLength: 500 },
        description: 'Links to documentation',
        maxItems: 10
      }
    },
    required: ['id'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: UpdateRequirementInput, context: RequestContext) {
    try {
      // Check if requirement exists
      const existing = await context.db.get(
        'SELECT * FROM product_requirements WHERE id = ? AND project_id = ?',
        [input.id, context.projectId || 'default']
      );

      if (!existing.success || !existing.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: `Requirement ${input.id} not found`,
          details: { requirementId: input.id },
          category: 'validation'
        });
      }

      const now = Date.now();
      const updates: string[] = ['updated_at = ?'];
      const values: any[] = [now];

      // Build update query dynamically
      if (input.name !== undefined) {
        updates.push('name = ?');
        values.push(input.name);
      }
      if (input.type !== undefined) {
        updates.push('type = ?');
        values.push(input.type);
      }
      if (input.description !== undefined) {
        updates.push('description = ?');
        values.push(input.description);
      }
      if (input.acceptanceCriteria !== undefined) {
        updates.push('acceptance_criteria = ?');
        values.push(JSON.stringify(input.acceptanceCriteria));
      }
      if (input.priority !== undefined) {
        updates.push('priority = ?');
        values.push(input.priority);
      }
      if (input.status !== undefined) {
        updates.push('status = ?');
        values.push(input.status);
        
        // Set approval info if moving to approved status
        if (input.status === 'approved' && existing.data.status !== 'approved') {
          updates.push('approved_by = ?', 'approved_at = ?');
          values.push(context.userId || 'system', now);
        }
      }
      if (input.tags !== undefined) {
        updates.push('tags = ?');
        values.push(JSON.stringify(input.tags));
      }
      if (input.businessValue !== undefined) {
        updates.push('business_value = ?');
        values.push(input.businessValue);
      }
      if (input.technicalNotes !== undefined) {
        updates.push('technical_notes = ?');
        values.push(input.technicalNotes);
      }
      if (input.testCriteria !== undefined) {
        updates.push('test_criteria = ?');
        values.push(JSON.stringify(input.testCriteria));
      }
      if (input.complianceRequirements !== undefined) {
        updates.push('compliance_requirements = ?');
        values.push(JSON.stringify(input.complianceRequirements));
      }
      if (input.estimatedEffort !== undefined) {
        updates.push('estimated_effort = ?');
        values.push(input.estimatedEffort);
      }
      if (input.actualEffort !== undefined) {
        updates.push('actual_effort = ?');
        values.push(input.actualEffort);
      }
      if (input.targetRelease !== undefined) {
        updates.push('target_release = ?');
        values.push(input.targetRelease);
      }
      if (input.documentationLinks !== undefined) {
        updates.push('documentation_links = ?');
        values.push(JSON.stringify(input.documentationLinks));
      }

      // Increment version
      updates.push('version = version + 1');

      values.push(input.id, context.projectId || 'default');

      const updateQuery = `UPDATE product_requirements SET ${updates.join(', ')} WHERE id = ? AND project_id = ?`;
      const result = await context.db.run(updateQuery, values);

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

      // Update repositories if provided
      if (input.repositories !== undefined) {
        // Delete existing repositories
        await context.db.run(
          'DELETE FROM requirement_repositories WHERE requirement_id = ?',
          [input.id]
        );

        // Insert new repositories
        for (const repo of input.repositories) {
          const repoId = `repo-${randomUUID()}`;
          await context.db.run(
            `INSERT INTO requirement_repositories 
             (id, requirement_id, project_id, name, implementation_status, branch, pr_url, notes, created_at, updated_at)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [
              repoId,
              input.id,
              context.projectId || 'default',
              repo.name,
              repo.implementationStatus,
              repo.branch || null,
              repo.prUrl || null,
              repo.notes || null,
              now,
              now
            ]
          );
        }
      }

      // Track changes
      const changedFields = Object.keys(input).filter(k => k !== 'id');
      for (const field of changedFields) {
        const changeId = `change-${randomUUID()}`;
        await context.db.run(
          `INSERT INTO requirement_changes 
           (id, requirement_id, project_id, field, old_value, new_value, changed_by, changed_at)
           VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
          [
            changeId,
            input.id,
            context.projectId || 'default',
            field,
            JSON.stringify(existing.data[field]),
            JSON.stringify((input as any)[field]),
            context.userId || 'system',
            now
          ]
        );
      }

      // Get updated requirement
      const updated = await context.db.get(
        'SELECT * FROM product_requirements WHERE id = ?',
        [input.id]
      );

      return createSuccessResult({
        requirement: {
          id: updated.data.id,
          name: updated.data.name,
          type: updated.data.type,
          status: updated.data.status,
          priority: updated.data.priority,
          version: updated.data.version
        },
        message: `Updated requirement "${updated.data.name}"`,
        fieldsUpdated: changedFields
      });

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

/**
 * Delete a product requirement
 */
const deleteRequirementTool = createTool<{ id: string }, any>({
  name: 'delete_requirement',
  description: 'Delete a product requirement',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      id: {
        type: 'string',
        description: 'Requirement ID to delete',
        pattern: '^req-[a-f0-9-]+$'
      }
    },
    required: ['id'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: { id: string }, context: RequestContext) {
    try {
      // Check if requirement exists
      const existing = await context.db.get(
        'SELECT * FROM product_requirements WHERE id = ? AND project_id = ?',
        [input.id, context.projectId || 'default']
      );

      if (!existing.success || !existing.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: `Requirement ${input.id} not found`,
          details: { requirementId: input.id },
          category: 'validation'
        });
      }

      // Check for child requirements
      const childIds = JSON.parse(existing.data.child_requirement_ids || '[]');
      if (childIds.length > 0) {
        return createErrorResult({
          code: 'VALIDATION_ERROR',
          message: 'Cannot delete requirement with child requirements',
          details: { childCount: childIds.length },
          category: 'validation'
        });
      }

      // Remove from parent's child list if applicable
      if (existing.data.parent_requirement_id) {
        const parent = await context.db.get(
          'SELECT child_requirement_ids FROM product_requirements WHERE id = ?',
          [existing.data.parent_requirement_id]
        );
        
        if (parent.success && parent.data) {
          const parentChildIds = JSON.parse(parent.data.child_requirement_ids || '[]');
          const updatedChildIds = parentChildIds.filter((id: string) => id !== input.id);
          
          await context.db.run(
            'UPDATE product_requirements SET child_requirement_ids = ?, updated_at = ? WHERE id = ?',
            [JSON.stringify(updatedChildIds), Date.now(), existing.data.parent_requirement_id]
          );
        }
      }

      // Delete requirement (cascades to repositories, story links, and changes)
      const result = await context.db.run(
        'DELETE FROM product_requirements WHERE id = ? AND project_id = ?',
        [input.id, context.projectId || 'default']
      );

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

      return createSuccessResult({
        deletedRequirement: {
          id: input.id,
          name: existing.data.name
        },
        message: `Deleted requirement "${existing.data.name}"`
      });

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

/**
 * Search product requirements by text query
 */
const searchRequirementsTool = createTool<SearchRequirementsInput, any>({
  name: 'search_requirements',
  description: 'Search product requirements by text query',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      query: {
        type: 'string',
        description: 'Search query',
        minLength: 2,
        maxLength: 200
      },
      searchIn: {
        type: 'array',
        items: {
          type: 'string',
          enum: ['name', 'description', 'acceptance_criteria', 'tags']
        },
        description: 'Fields to search in (default: name, description)',
        maxItems: 4
      },
      limit: {
        type: 'number',
        description: 'Maximum results to return',
        minimum: 1,
        maximum: 100,
        default: 20
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
        minimum: 0,
        default: 0
      }
    },
    required: ['query'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: SearchRequirementsInput, context: RequestContext) {
    try {
      const searchFields = input.searchIn || ['name', 'description'];
      const searchConditions: string[] = [];
      const params: any[] = [];

      // Build search conditions
      if (searchFields.includes('name')) {
        searchConditions.push('r.name LIKE ?');
        params.push(`%${input.query}%`);
      }
      if (searchFields.includes('description')) {
        searchConditions.push('r.description LIKE ?');
        params.push(`%${input.query}%`);
      }
      if (searchFields.includes('acceptance_criteria')) {
        searchConditions.push('r.acceptance_criteria LIKE ?');
        params.push(`%${input.query}%`);
      }
      if (searchFields.includes('tags')) {
        searchConditions.push('r.tags LIKE ?');
        params.push(`%${input.query}%`);
      }

      const query = `
        SELECT r.*,
        (SELECT COUNT(*) FROM requirement_repositories WHERE requirement_id = r.id) as repo_count,
        (SELECT COUNT(*) FROM requirement_story_links WHERE requirement_id = r.id) as story_count
        FROM product_requirements r
        WHERE r.project_id = ? AND (${searchConditions.join(' OR ')})
        ORDER BY 
          CASE 
            WHEN r.name LIKE ? THEN 1
            WHEN r.description LIKE ? THEN 2
            ELSE 3
          END,
          r.updated_at DESC
        LIMIT ? OFFSET ?
      `;

      const allParams = [
        context.projectId || 'default',
        ...params,
        `${input.query}%`, // For relevance sorting
        `${input.query}%`,
        input.limit || 20,
        input.offset || 0
      ];

      const results = await context.db.all(query, allParams);

      if (!results.success) {
        return createErrorResult({
          code: 'DATABASE_ERROR',
          message: 'Failed to search requirements',
          details: { error: results.error },
          category: 'system'
        });
      }

      if (results.data.length === 0) {
        return createSuccessResult({
          requirements: [],
          totalFound: 0,
          message: `No requirements found matching "${input.query}"`
        });
      }

      const requirements = results.data.map((req: any) => ({
        id: req.id,
        name: req.name,
        type: req.type,
        description: req.description.substring(0, 200) + (req.description.length > 200 ? '...' : ''),
        priority: req.priority,
        status: req.status,
        tags: JSON.parse(req.tags || '[]'),
        repositoryCount: req.repo_count,
        storyCount: req.story_count,
        relevanceScore: req.name.toLowerCase().includes(input.query.toLowerCase()) ? 100 : 50
      }));

      return createSuccessResult({
        requirements,
        totalFound: requirements.length,
        query: input.query,
        searchedIn: searchFields,
        message: `Found ${requirements.length} requirement(s) matching "${input.query}"`
      });

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

/**
 * Link a product requirement to a user story
 */
const linkRequirementToStoryTool = createTool<LinkRequirementToStoryInput, any>({
  name: 'link_requirement_to_story',
  description: 'Link a product requirement to a user story',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      requirementId: {
        type: 'string',
        description: 'Product requirement ID',
        pattern: '^req-[a-f0-9-]+$'
      },
      storyId: {
        type: 'string',
        description: 'User story ID'
      },
      linkType: {
        type: 'string',
        enum: ['implements', 'relates_to', 'depends_on'],
        description: 'Type of relationship',
        default: 'implements'
      },
      notes: {
        type: 'string',
        description: 'Additional notes about the link',
        maxLength: 1000
      }
    },
    required: ['requirementId', 'storyId'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: LinkRequirementToStoryInput, context: RequestContext) {
    try {
      // Verify requirement exists
      const reqCheck = await context.db.get(
        'SELECT id, related_stories FROM product_requirements WHERE id = ? AND project_id = ?',
        [input.requirementId, context.projectId || 'default']
      );

      if (!reqCheck.success || !reqCheck.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: 'Requirement not found',
          details: { requirementId: input.requirementId },
          category: 'validation'
        });
      }

      // Verify story exists
      const storyCheck = await context.db.get(
        'SELECT id FROM agile_stories WHERE id = ? AND project_id = ?',
        [input.storyId, context.projectId || 'default']
      );

      if (!storyCheck.success || !storyCheck.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: 'Story not found',
          details: { storyId: input.storyId },
          category: 'validation'
        });
      }

      // Check if link already exists
      const existingLink = await context.db.get(
        'SELECT id FROM requirement_story_links WHERE requirement_id = ? AND story_id = ?',
        [input.requirementId, input.storyId]
      );

      if (existingLink.success && existingLink.data) {
        return createErrorResult({
          code: 'DUPLICATE_RESOURCE',
          message: 'Link already exists between this requirement and story',
          category: 'validation'
        });
      }

      const linkId = `link-${randomUUID()}`;
      const now = Date.now();

      // Create link
      const result = await context.db.run(
        `INSERT INTO requirement_story_links 
         (id, requirement_id, story_id, project_id, link_type, notes, created_at)
         VALUES (?, ?, ?, ?, ?, ?, ?)`,
        [
          linkId,
          input.requirementId,
          input.storyId,
          context.projectId || 'default',
          input.linkType || 'implements',
          input.notes || null,
          now
        ]
      );

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

      // Update requirement's related_stories array
      const relatedStories = JSON.parse(reqCheck.data.related_stories || '[]');
      if (!relatedStories.includes(input.storyId)) {
        relatedStories.push(input.storyId);
        
        await context.db.run(
          'UPDATE product_requirements SET related_stories = ?, updated_at = ? WHERE id = ?',
          [JSON.stringify(relatedStories), now, input.requirementId]
        );
      }

      return createSuccessResult({
        link: {
          id: linkId,
          requirementId: input.requirementId,
          storyId: input.storyId,
          linkType: input.linkType || 'implements',
          notes: input.notes
        },
        message: `Linked requirement ${input.requirementId} to story ${input.storyId}`,
        nextSteps: [
          'Update story to reflect requirement implementation',
          'Track progress through story status updates'
        ]
      });

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

/**
 * Update implementation status for a requirement in a specific repository
 */
const updateImplementationStatusTool = createTool<UpdateImplementationStatusInput, any>({
  name: 'update_implementation_status',
  description: 'Update implementation status for a requirement in a specific repository',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      requirementId: {
        type: 'string',
        description: 'Product requirement ID',
        pattern: '^req-[a-f0-9-]+$'
      },
      repositoryName: {
        type: 'string',
        description: 'Repository name',
        minLength: 1,
        maxLength: 100
      },
      status: {
        type: 'string',
        enum: ['not_started', 'in_progress', 'completed', 'blocked'],
        description: 'New implementation status'
      },
      branch: {
        type: 'string',
        description: 'Branch name where implementation is happening',
        maxLength: 100
      },
      prUrl: {
        type: 'string',
        description: 'Pull request URL',
        maxLength: 500
      },
      notes: {
        type: 'string',
        description: 'Implementation notes',
        maxLength: 1000
      }
    },
    required: ['requirementId', 'repositoryName', 'status'],
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: UpdateImplementationStatusInput, context: RequestContext) {
    try {
      // Verify requirement exists
      const reqCheck = await context.db.get(
        'SELECT id FROM product_requirements WHERE id = ? AND project_id = ?',
        [input.requirementId, context.projectId || 'default']
      );

      if (!reqCheck.success || !reqCheck.data) {
        return createErrorResult({
          code: 'RESOURCE_NOT_FOUND',
          message: 'Requirement not found',
          details: { requirementId: input.requirementId },
          category: 'validation'
        });
      }

      // Check if repository exists for this requirement
      const repoCheck = await context.db.get(
        'SELECT id FROM requirement_repositories WHERE requirement_id = ? AND name = ?',
        [input.requirementId, input.repositoryName]
      );

      const now = Date.now();

      if (repoCheck.success && repoCheck.data) {
        // Update existing repository
        const result = await context.db.run(
          `UPDATE requirement_repositories 
           SET implementation_status = ?, branch = ?, pr_url = ?, notes = ?, updated_at = ?
           WHERE id = ?`,
          [
            input.status,
            input.branch || null,
            input.prUrl || null,
            input.notes || null,
            now,
            repoCheck.data.id
          ]
        );

        if (!result.success) {
          return createErrorResult({
            code: 'DATABASE_ERROR',
            message: 'Failed to update implementation status',
            details: { error: result.error },
            category: 'system'
          });
        }
      } else {
        // Create new repository entry
        const repoId = `repo-${randomUUID()}`;
        const result = await context.db.run(
          `INSERT INTO requirement_repositories 
           (id, requirement_id, project_id, name, implementation_status, branch, pr_url, notes, created_at, updated_at)
           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
          [
            repoId,
            input.requirementId,
            context.projectId || 'default',
            input.repositoryName,
            input.status,
            input.branch || null,
            input.prUrl || null,
            input.notes || null,
            now,
            now
          ]
        );

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

      // Update requirement's updated_at timestamp
      await context.db.run(
        'UPDATE product_requirements SET updated_at = ? WHERE id = ?',
        [now, input.requirementId]
      );

      // Track the change
      const changeId = `change-${randomUUID()}`;
      await context.db.run(
        `INSERT INTO requirement_changes 
         (id, requirement_id, project_id, field, old_value, new_value, changed_by, changed_at, reason)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          changeId,
          input.requirementId,
          context.projectId || 'default',
          `implementation_status_${input.repositoryName}`,
          repoCheck.data ? repoCheck.data.implementation_status : null,
          input.status,
          context.userId || 'system',
          now,
          input.notes || null
        ]
      );

      return createSuccessResult({
        requirementId: input.requirementId,
        repository: {
          name: input.repositoryName,
          status: input.status,
          branch: input.branch,
          prUrl: input.prUrl
        },
        message: `Updated implementation status for repository "${input.repositoryName}" to "${input.status}"`,
        nextSteps: input.status === 'completed' ? [
          'Verify all acceptance criteria are met',
          'Update requirement status if all repositories are complete'
        ] : input.status === 'blocked' ? [
          'Document blocker details in notes',
          'Create issue to track resolution'
        ] : []
      });

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

/**
 * Generate a comprehensive requirements report
 */
const generateRequirementsReportTool = createTool<GenerateReportInput, any>({
  name: 'generate_requirements_report',
  description: 'Generate a comprehensive requirements report',
  category: 'product-requirements',
  inputSchema: {
    type: 'object',
    properties: {
      format: {
        type: 'string',
        enum: ['json', 'markdown', 'html'],
        description: 'Report format',
        default: 'json'
      },
      includeImplementationStatus: {
        type: 'boolean',
        description: 'Include detailed implementation status',
        default: true
      },
      groupBy: {
        type: 'string',
        enum: ['type', 'status', 'priority'],
        description: 'Group requirements by this field'
      },
      filterType: {
        type: 'string',
        enum: ['functional', 'non-functional', 'business', 'technical', 'user-interface', 'security', 'performance'],
        description: 'Filter by requirement type'
      },
      filterStatus: {
        type: 'string',
        enum: ['draft', 'approved', 'in_development', 'implemented', 'deprecated'],
        description: 'Filter by status'
      },
      filterPriority: {
        type: 'string',
        enum: ['low', 'medium', 'high', 'critical'],
        description: 'Filter by priority'
      }
    },
    additionalProperties: false
  } as JSONSchema7,

  async execute(input: GenerateReportInput, context: RequestContext) {
    try {
      // Build query with filters
      let query = `
        SELECT r.*,
        (SELECT COUNT(*) FROM requirement_repositories WHERE requirement_id = r.id) as repo_count,
        (SELECT COUNT(*) FROM requirement_repositories WHERE requirement_id = r.id AND implementation_status = 'completed') as repos_completed,
        (SELECT COUNT(*) FROM requirement_story_links WHERE requirement_id = r.id) as story_count
        FROM product_requirements r
        WHERE r.project_id = ?
      `;
      const params: any[] = [context.projectId || 'default'];

      if (input.filterType) {
        query += ' AND r.type = ?';
        params.push(input.filterType);
      }
      if (input.filterStatus) {
        query += ' AND r.status = ?';
        params.push(input.filterStatus);
      }
      if (input.filterPriority) {
        query += ' AND r.priority = ?';
        params.push(input.filterPriority);
      }

      query += ' ORDER BY r.priority DESC, r.created_at DESC';

      const requirements = await context.db.all(query, params);

      if (!requirements.success) {
        return createErrorResult({
          code: 'DATABASE_ERROR',
          message: 'Failed to fetch requirements for report',
          details: { error: requirements.error },
          category: 'system'
        });
      }

      // Calculate summary statistics
      const summary = {
        total_requirements: requirements.data.length,
        by_type: {} as Record<string, number>,
        by_status: {} as Record<string, number>,
        by_priority: {} as Record<string, number>,
        implementation_progress: {
          not_started: 0,
          in_progress: 0,
          completed: 0,
          blocked: 0
        }
      };

      // Get implementation details if requested
      let requirementsData = requirements.data;
      if (input.includeImplementationStatus) {
        requirementsData = await Promise.all(
          requirements.data.map(async (req: any) => {
            const repos = await context.db.all(
              'SELECT * FROM requirement_repositories WHERE requirement_id = ?',
              [req.id]
            );

            const implementationSummary = {
              not_started: 0,
              in_progress: 0,
              completed: 0,
              blocked: 0
            };

            if (repos.success) {
              repos.data.forEach((repo: any) => {
                implementationSummary[repo.implementation_status as keyof typeof implementationSummary]++;
              });
            }

            // Determine overall implementation status
            let overallStatus = 'not_started';
            if (implementationSummary.blocked > 0) {
              overallStatus = 'blocked';
            } else if (implementationSummary.completed === req.repo_count && req.repo_count > 0) {
              overallStatus = 'completed';
            } else if (implementationSummary.in_progress > 0 || implementationSummary.completed > 0) {
              overallStatus = 'in_progress';
            }

            summary.implementation_progress[overallStatus as keyof typeof summary.implementation_progress]++;

            return {
              ...req,
              repositories: repos.success ? repos.data : [],
              implementation_summary: implementationSummary,
              overall_implementation_status: overallStatus
            };
          })
        );
      }

      // Calculate type/status/priority counts
      requirementsData.forEach((req: any) => {
        summary.by_type[req.type] = (summary.by_type[req.type] || 0) + 1;
        summary.by_status[req.status] = (summary.by_status[req.status] || 0) + 1;
        summary.by_priority[req.priority] = (summary.by_priority[req.priority] || 0) + 1;
      });

      // Group requirements if requested
      let groupedRequirements: any = null;
      if (input.groupBy) {
        groupedRequirements = {};
        requirementsData.forEach((req: any) => {
          const groupKey = req[input.groupBy!];
          if (!groupedRequirements[groupKey]) {
            groupedRequirements[groupKey] = [];
          }
          groupedRequirements[groupKey].push({
            id: req.id,
            name: req.name,
            priority: req.priority,
            status: req.status,
            implementation_status: req.overall_implementation_status,
            story_count: req.story_count
          });
        });
      }

      // Format report based on requested format
      let formattedReport: any;
      const reportData = {
        summary,
        requirements: input.groupBy ? groupedRequirements : requirementsData.map((r: any) => ({
          id: r.id,
          name: r.name,
          type: r.type,
          description: r.description,
          priority: r.priority,
          status: r.status,
          tags: JSON.parse(r.tags || '[]'),
          story_count: r.story_count,
          repository_count: r.repo_count,
          implementation_status: r.overall_implementation_status,
          repositories: r.repositories
        })),
        generated_at: new Date().toISOString(),
        format: input.format || 'json'
      };

      if (input.format === 'markdown') {
        let markdown = '# Product Requirements Report\n\n';
        markdown += `Generated: ${reportData.generated_at}\n\n`;
        markdown += '## Summary\n\n';
        markdown += `- Total Requirements: ${summary.total_requirements}\n`;
        markdown += '\n### By Type\n';
        Object.entries(summary.by_type).forEach(([type, count]) => {
          markdown += `- ${type}: ${count}\n`;
        });
        markdown += '\n### By Status\n';
        Object.entries(summary.by_status).forEach(([status, count]) => {
          markdown += `- ${status}: ${count}\n`;
        });
        markdown += '\n### By Priority\n';
        Object.entries(summary.by_priority).forEach(([priority, count]) => {
          markdown += `- ${priority}: ${count}\n`;
        });
        markdown += '\n### Implementation Progress\n';
        Object.entries(summary.implementation_progress).forEach(([status, count]) => {
          markdown += `- ${status.replace('_', ' ')}: ${count}\n`;
        });

        formattedReport = markdown;
      } else {
        formattedReport = reportData;
      }

      return createSuccessResult({
        report: formattedReport,
        summary,
        message: `Generated requirements report with ${summary.total_requirements} requirement(s)`,
        insights: [
          `${summary.by_status.approved || 0} requirements approved and ready for implementation`,
          `${summary.implementation_progress.completed} requirements fully implemented`,
          `${summary.implementation_progress.blocked} requirements currently blocked`
        ]
      });

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

/**
 * Setup all product requirements tools
 */
export async function setupProductRequirementsTools(): Promise<ToolRegistration> {
  return {
    module: 'product-requirements',
    tools: [
      createRequirementTool,
      listRequirementsTool,
      getRequirementTool,
      updateRequirementTool,
      deleteRequirementTool,
      searchRequirementsTool,
      linkRequirementToStoryTool,
      updateImplementationStatusTool,
      generateRequirementsReportTool
    ]
  };
}