import { EventEmitter } from 'events';
import { writeFile, readFile, mkdir, readdir, stat } from 'fs/promises';
import { join } from 'path';
import { Logger } from '../core/logger.js';
import { ConfigManager } from '../core/config.js';

export interface ProjectPhase {
  id: string;
  name: string;
  description: string;
  status: 'planned' | 'in-progress' | 'completed' | 'blocked' | 'cancelled';
  startDate?: Date;
  endDate?: Date;
  estimatedDuration: number; // in hours
  actualDuration?: number;
  dependencies: string[];
  assignedTeam: string[];
  deliverables: string[];
  risks: ProjectRisk[];
  milestones: ProjectMilestone[];
  budget: {
    estimated: number;
    actual: number;
    currency: string;
  };
  resources: ProjectResource[];
  completionPercentage: number;
  qualityMetrics: {
    testCoverage: number;
    codeQuality: number;
    documentation: number;
    securityScore: number;
  };
}

export interface ProjectRisk {
  id: string;
  description: string;
  probability: 'low' | 'medium' | 'high';
  impact: 'low' | 'medium' | 'high';
  mitigation: string;
  status: 'open' | 'mitigated' | 'closed';
  assignedTo: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface ProjectMilestone {
  id: string;
  name: string;
  description: string;
  targetDate: Date;
  actualDate?: Date;
  status: 'pending' | 'achieved' | 'missed' | 'at-risk';
  dependencies: string[];
  deliverables: string[];
  successCriteria: string[];
}

export interface ProjectResource {
  id: string;
  name: string;
  type: 'human' | 'infrastructure' | 'software' | 'hardware';
  availability: number; // percentage
  cost: {
    amount: number;
    currency: string;
    period: 'hour' | 'day' | 'week' | 'month';
  };
  skills: string[];
  allocation: {
    phaseId: string;
    percentage: number;
    startDate: Date;
    endDate: Date;
  }[];
}

export interface Project {
  id: string;
  name: string;
  description: string;
  type: 'web-app' | 'api' | 'microservice' | 'infrastructure' | 'research' | 'migration' | 'custom';
  status: 'planning' | 'active' | 'on-hold' | 'completed' | 'cancelled';
  priority: 'low' | 'medium' | 'high' | 'critical';
  owner: string;
  stakeholders: string[];
  phases: ProjectPhase[];
  budget: {
    total: number;
    spent: number;
    remaining: number;
    currency: string;
  };
  timeline: {
    plannedStart: Date;
    plannedEnd: Date;
    actualStart?: Date;
    actualEnd?: Date;
  };
  tags: string[];
  metadata: Record<string, any>;
  createdAt: Date;
  updatedAt: Date;
  auditLog: ProjectAuditEntry[];
  collaboration: {
    teamMembers: TeamMember[];
    communication: CommunicationChannel[];
    sharedResources: string[];
  };
  qualityGates: QualityGate[];
  complianceRequirements: ComplianceRequirement[];
}

export interface TeamMember {
  id: string;
  name: string;
  email: string;
  role: string;
  skills: string[];
  availability: number;
  permissions: string[];
  joinDate: Date;
  status: 'active' | 'inactive' | 'on-leave';
}

export interface CommunicationChannel {
  id: string;
  name: string;
  type: 'slack' | 'teams' | 'email' | 'webhook' | 'custom';
  configuration: Record<string, any>;
  isActive: boolean;
}

export interface QualityGate {
  id: string;
  name: string;
  phase: string;
  criteria: {
    metric: string;
    threshold: number;
    operator: '>' | '<' | '>=' | '<=' | '==' | '!=';
  }[];
  status: 'pending' | 'passed' | 'failed' | 'skipped';
  executedAt?: Date;
  results: Record<string, number>;
}

export interface ComplianceRequirement {
  id: string;
  name: string;
  framework: string; // e.g., 'SOC2', 'GDPR', 'HIPAA', 'PCI-DSS'
  description: string;
  status: 'not-started' | 'in-progress' | 'compliant' | 'non-compliant';
  evidence: string[];
  reviewer: string;
  reviewDate?: Date;
  dueDate: Date;
}

export interface ProjectAuditEntry {
  id: string;
  timestamp: Date;
  userId: string;
  action: string;
  target: string;
  details: Record<string, any>;
  ipAddress?: string;
  userAgent?: string;
}

export interface ProjectMetrics {
  totalProjects: number;
  activeProjects: number;
  completedProjects: number;
  averageProjectDuration: number;
  budgetVariance: number;
  resourceUtilization: number;
  qualityScore: number;
  riskScore: number;
  teamProductivity: number;
  customerSatisfaction: number;
}

export interface ProjectReport {
  id: string;
  projectId: string;
  type: 'status' | 'financial' | 'quality' | 'risk' | 'resource' | 'compliance';
  title: string;
  summary: string;
  details: Record<string, any>;
  recommendations: string[];
  generatedAt: Date;
  generatedBy: string;
  format: 'json' | 'pdf' | 'html' | 'csv';
  recipients: string[];
}

export class ProjectManager extends EventEmitter {
  private projects: Map<string, Project> = new Map();
  private projectsPath: string;
  private logger: Logger;
  private config: ConfigManager;

  constructor(projectsPath: string = './projects', logger?: Logger, config?: ConfigManager) {
    super();
    this.projectsPath = projectsPath;
    this.logger = logger || new Logger({ level: 'info', format: 'text', destination: 'console' });
    this.config = config || ConfigManager.getInstance();
  }

  async initialize(): Promise<void> {
    try {
      await mkdir(this.projectsPath, { recursive: true });
      await this.loadProjects();
      this.logger.info('Project Manager initialized successfully');
    } catch (error) {
      this.logger.error('Failed to initialize Project Manager', { error });
      throw error;
    }
  }

  async createProject(projectData: Partial<Project>): Promise<Project> {
    const project: Project = {
      id: projectData.id || `project-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      name: projectData.name || 'Unnamed Project',
      description: projectData.description || '',
      type: projectData.type || 'custom',
      status: 'planning',
      priority: projectData.priority || 'medium',
      owner: projectData.owner || 'system',
      stakeholders: projectData.stakeholders || [],
      phases: projectData.phases || [],
      budget: projectData.budget || {
        total: 0,
        spent: 0,
        remaining: 0,
        currency: 'USD',
      },
      timeline: {
        plannedStart: projectData.timeline?.plannedStart || new Date(),
        plannedEnd:
          projectData.timeline?.plannedEnd || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
        actualStart: projectData.timeline?.actualStart,
        actualEnd: projectData.timeline?.actualEnd,
      },
      tags: projectData.tags || [],
      metadata: projectData.metadata || {},
      createdAt: new Date(),
      updatedAt: new Date(),
      auditLog: [],
      collaboration: {
        teamMembers: [],
        communication: [],
        sharedResources: [],
      },
      qualityGates: [],
      complianceRequirements: [],
    };

    // Add initial audit entry
    this.addAuditEntry(project, 'system', 'project_created', 'project', {
      projectId: project.id,
      projectName: project.name,
    });

    this.projects.set(project.id, project);
    await this.saveProject(project);

    this.emit('project:created', project);
    this.logger.info(`Project created: ${project.name} (${project.id})`);

    return project;
  }

  async updateProject(projectId: string, updates: Partial<Project>): Promise<Project> {
    const project = this.projects.get(projectId);
    if (!project) {
      throw new Error(`Project not found: ${projectId}`);
    }

    const updatedProject = { ...project, ...updates, updatedAt: new Date() };

    // Add audit entry
    this.addAuditEntry(updatedProject, 'system', 'project_updated', 'project', {
      projectId,
      changes: Object.keys(updates),
    });

    this.projects.set(projectId, updatedProject);
    await this.saveProject(updatedProject);

    this.emit('project:updated', updatedProject);
    this.logger.info(`Project updated: ${project.name} (${projectId})`);

    return updatedProject;
  }

  async deleteProject(projectId: string, userId: string = 'system'): Promise<void> {
    const project = this.projects.get(projectId);
    if (!project) {
      throw new Error(`Project not found: ${projectId}`);
    }

    // Add audit entry before deletion
    this.addAuditEntry(project, userId, 'project_deleted', 'project', {
      projectId,
      projectName: project.name,
    });

    this.projects.delete(projectId);

    // Archive project instead of deleting
    const archivePath = join(this.projectsPath, 'archived');
    await mkdir(archivePath, { recursive: true });
    await writeFile(join(archivePath, `${projectId}.json`), JSON.stringify(project, null, 2));

    this.emit('project:deleted', { projectId, project });
    this.logger.info(`Project archived: ${project.name} (${projectId})`);
  }

  async getProject(projectId: string): Promise<Project | null> {
    return this.projects.get(projectId) || null;
  }

  async listProjects(filters?: {
    status?: Project['status'];
    type?: Project['type'];
    priority?: Project['priority'];
    owner?: string;
    tags?: string[];
  }): Promise<Project[]> {
    let projects = Array.from(this.projects.values());

    if (filters) {
      if (filters.status) {
        projects = projects.filter((p) => p.status === filters.status);
      }
      if (filters.type) {
        projects = projects.filter((p) => p.type === filters.type);
      }
      if (filters.priority) {
        projects = projects.filter((p) => p.priority === filters.priority);
      }
      if (filters.owner) {
        projects = projects.filter((p) => p.owner === filters.owner);
      }
      if (filters.tags && filters.tags.length > 0) {
        projects = projects.filter((p) => filters.tags!.some((tag) => p.tags.includes(tag)));
      }
    }

    return projects.sort(
      (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),
    );
  }

  async addPhase(projectId: string, phase: Omit<ProjectPhase, 'id'>): Promise<ProjectPhase> {
    const project = this.projects.get(projectId);
    if (!project) {
      throw new Error(`Project not found: ${projectId}`);
    }

    const newPhase: ProjectPhase = {
      id: `phase-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      ...phase,
    };

    project.phases.push(newPhase);
    project.updatedAt = new Date();

    this.addAuditEntry(project, 'system', 'phase_added', 'phase', {
      projectId,
      phaseId: newPhase.id,
      phaseName: newPhase.name,
    });

    await this.saveProject(project);
    this.emit('phase:added', { project, phase: newPhase });

    return newPhase;
  }

  async updatePhase(
    projectId: string,
    phaseId: string,
    updates: Partial<ProjectPhase>,
  ): Promise<ProjectPhase> {
    const project = this.projects.get(projectId);
    if (!project) {
      throw new Error(`Project not found: ${projectId}`);
    }

    const phaseIndex = project.phases.findIndex((p) => p.id === phaseId);
    if (phaseIndex === -1) {
      throw new Error(`Phase not found: ${phaseId}`);
    }

    const updatedPhase = { ...project.phases[phaseIndex], ...updates };
    project.phases[phaseIndex] = updatedPhase;
    project.updatedAt = new Date();

    this.addAuditEntry(project, 'system', 'phase_updated', 'phase', {
      projectId,
      phaseId,
      changes: Object.keys(updates),
    });

    await this.saveProject(project);
    this.emit('phase:updated', { project, phase: updatedPhase });

    return updatedPhase;
  }

  async addTeamMember(projectId: string, member: TeamMember): Promise<void> {
    const project = this.projects.get(projectId);
    if (!project) {
      throw new Error(`Project not found: ${projectId}`);
    }

    project.collaboration.teamMembers.push(member);
    project.updatedAt = new Date();

    this.addAuditEntry(project, 'system', 'team_member_added', 'team', {
      projectId,
      memberId: member.id,
      memberName: member.name,
    });

    await this.saveProject(project);
    this.emit('team:member_added', { project, member });
  }

  async removeTeamMember(projectId: string, memberId: string): Promise<void> {
    const project = this.projects.get(projectId);
    if (!project) {
      throw new Error(`Project not found: ${projectId}`);
    }

    const memberIndex = project.collaboration.teamMembers.findIndex((m) => m.id === memberId);
    if (memberIndex === -1) {
      throw new Error(`Team member not found: ${memberId}`);
    }

    const member = project.collaboration.teamMembers[memberIndex];
    project.collaboration.teamMembers.splice(memberIndex, 1);
    project.updatedAt = new Date();

    this.addAuditEntry(project, 'system', 'team_member_removed', 'team', {
      projectId,
      memberId,
      memberName: member.name,
    });

    await this.saveProject(project);
    this.emit('team:member_removed', { project, memberId });
  }

  async getProjectMetrics(projectId?: string): Promise<ProjectMetrics> {
    const projects = projectId
      ? ([this.projects.get(projectId)].filter(Boolean) as Project[])
      : Array.from(this.projects.values());

    const totalProjects = projects.length;
    const activeProjects = projects.filter((p) => p.status === 'active').length;
    const completedProjects = projects.filter((p) => p.status === 'completed').length;

    const completedProjectsWithDuration = projects.filter(
      (p) => p.status === 'completed' && p.timeline.actualStart && p.timeline.actualEnd,
    );

    const averageProjectDuration =
      completedProjectsWithDuration.length > 0
        ? completedProjectsWithDuration.reduce((sum, p) => {
            const duration = p.timeline.actualEnd!.getTime() - p.timeline.actualStart!.getTime();
            return sum + duration / (1000 * 60 * 60 * 24); // Convert to days
          }, 0) / completedProjectsWithDuration.length
        : 0;

    const budgetVariance =
      projects.reduce((sum, p) => {
        if (p.budget.total > 0) {
          return sum + (p.budget.spent - p.budget.total) / p.budget.total;
        }
        return sum;
      }, 0) / Math.max(projects.length, 1);

    const resourceUtilization =
      projects.reduce((sum, p) => {
        const totalResources = p.phases.reduce(
          (phaseSum, phase) => phaseSum + phase.resources.length,
          0,
        );
        const utilizedResources = p.phases.reduce(
          (phaseSum, phase) => phaseSum + phase.resources.filter((r) => r.availability > 0).length,
          0,
        );
        return sum + (totalResources > 0 ? utilizedResources / totalResources : 0);
      }, 0) / Math.max(projects.length, 1);

    const qualityScore =
      projects.reduce((sum, p) => {
        const phaseQuality =
          p.phases.reduce((phaseSum, phase) => {
            const metrics = phase.qualityMetrics;
            return (
              phaseSum +
              (metrics.testCoverage +
                metrics.codeQuality +
                metrics.documentation +
                metrics.securityScore) /
                4
            );
          }, 0) / Math.max(p.phases.length, 1);
        return sum + phaseQuality;
      }, 0) / Math.max(projects.length, 1);

    return {
      totalProjects,
      activeProjects,
      completedProjects,
      averageProjectDuration,
      budgetVariance,
      resourceUtilization,
      qualityScore,
      riskScore: 0, // Calculate based on risk assessment
      teamProductivity: 0, // Calculate based on velocity metrics
      customerSatisfaction: 0, // Calculate based on feedback
    };
  }

  async generateReport(
    projectId: string,
    type: ProjectReport['type'],
    userId: string = 'system',
  ): Promise<ProjectReport> {
    const project = this.projects.get(projectId);
    if (!project) {
      throw new Error(`Project not found: ${projectId}`);
    }

    const report: ProjectReport = {
      id: `report-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      projectId,
      type,
      title: `${type.toUpperCase()} Report - ${project.name}`,
      summary: '',
      details: {},
      recommendations: [],
      generatedAt: new Date(),
      generatedBy: userId,
      format: 'json',
      recipients: [],
    };

    switch (type) {
      case 'status':
        report.summary = `Project ${project.name} is currently ${project.status}`;
        report.details = {
          status: project.status,
          progress: this.calculateProjectProgress(project),
          phases: project.phases.map((p) => ({
            name: p.name,
            status: p.status,
            completion: p.completionPercentage,
          })),
          timeline: project.timeline,
          nextMilestones: this.getUpcomingMilestones(project),
        };
        break;

      case 'financial':
        report.summary = `Budget utilization: ${((project.budget.spent / project.budget.total) * 100).toFixed(1)}%`;
        report.details = {
          budget: project.budget,
          costBreakdown: this.calculateCostBreakdown(project),
          variance: project.budget.spent - project.budget.total,
          projectedCost: this.projectFinalCost(project),
        };
        break;

      case 'quality':
        const qualityMetrics = this.calculateQualityMetrics(project);
        report.summary = `Overall quality score: ${qualityMetrics.overall.toFixed(1)}%`;
        report.details = {
          qualityMetrics,
          qualityGates: project.qualityGates,
          recommendations: this.generateQualityRecommendations(project),
        };
        break;

      case 'risk':
        const risks = this.getAllRisks(project);
        report.summary = `${risks.filter((r) => r.status === 'open').length} open risks identified`;
        report.details = {
          risks,
          riskMatrix: this.generateRiskMatrix(risks),
          mitigation: this.generateRiskMitigation(risks),
        };
        break;

      case 'resource':
        report.summary = `${project.collaboration.teamMembers.length} team members, ${this.getTotalResources(project)} resources allocated`;
        report.details = {
          teamMembers: project.collaboration.teamMembers,
          resourceAllocation: this.calculateResourceAllocation(project),
          utilization: this.calculateResourceUtilization(project),
          capacity: this.calculateCapacity(project),
        };
        break;

      case 'compliance':
        const compliance = this.calculateComplianceStatus(project);
        report.summary = `${compliance.compliant} of ${compliance.total} requirements met`;
        report.details = {
          requirements: project.complianceRequirements,
          status: compliance,
          gaps: this.identifyComplianceGaps(project),
          recommendations: this.generateComplianceRecommendations(project),
        };
        break;
    }

    this.addAuditEntry(project, userId, 'report_generated', 'report', {
      projectId,
      reportId: report.id,
      reportType: type,
    });

    this.emit('report:generated', { project, report });
    return report;
  }

  private async loadProjects(): Promise<void> {
    try {
      const files = await readdir(this.projectsPath);
      const projectFiles = files.filter((f) => f.endsWith('.json') && !f.startsWith('.'));

      for (const file of projectFiles) {
        try {
          const content = await readFile(join(this.projectsPath, file), 'utf-8');
          const project: Project = JSON.parse(content);
          this.projects.set(project.id, project);
        } catch (error) {
          this.logger.error(`Failed to load project file: ${file}`, { error });
        }
      }

      this.logger.info(`Loaded ${this.projects.size} projects`);
    } catch (error) {
      this.logger.error('Failed to load projects', { error });
    }
  }

  private async saveProject(project: Project): Promise<void> {
    const filePath = join(this.projectsPath, `${project.id}.json`);
    await writeFile(filePath, JSON.stringify(project, null, 2));
  }

  private addAuditEntry(
    project: Project,
    userId: string,
    action: string,
    target: string,
    details: Record<string, any>,
  ): void {
    const entry: ProjectAuditEntry = {
      id: `audit-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      timestamp: new Date(),
      userId,
      action,
      target,
      details,
    };

    project.auditLog.push(entry);
  }

  private calculateProjectProgress(project: Project): number {
    if (project.phases.length === 0) return 0;

    const totalProgress = project.phases.reduce(
      (sum, phase) => sum + phase.completionPercentage,
      0,
    );

    return totalProgress / project.phases.length;
  }

  private getUpcomingMilestones(project: Project): ProjectMilestone[] {
    const allMilestones = project.phases.flatMap((p) => p.milestones);
    const now = new Date();

    return allMilestones
      .filter((m) => m.status === 'pending' && m.targetDate > now)
      .sort((a, b) => a.targetDate.getTime() - b.targetDate.getTime())
      .slice(0, 5);
  }

  private calculateCostBreakdown(project: Project): Record<string, number> {
    const breakdown: Record<string, number> = {};

    for (const phase of project.phases) {
      for (const resource of phase.resources) {
        const category = resource.type;
        const cost = resource.cost.amount;
        breakdown[category] = (breakdown[category] || 0) + cost;
      }
    }

    return breakdown;
  }

  private projectFinalCost(project: Project): number {
    const progress = this.calculateProjectProgress(project);
    if (progress === 0) return project.budget.total;

    return (project.budget.spent / progress) * 100;
  }

  private calculateQualityMetrics(project: Project): any {
    const allMetrics = project.phases.map((p) => p.qualityMetrics);
    if (allMetrics.length === 0) {
      return { overall: 0, testCoverage: 0, codeQuality: 0, documentation: 0, securityScore: 0 };
    }

    const averages = {
      testCoverage: allMetrics.reduce((sum, m) => sum + m.testCoverage, 0) / allMetrics.length,
      codeQuality: allMetrics.reduce((sum, m) => sum + m.codeQuality, 0) / allMetrics.length,
      documentation: allMetrics.reduce((sum, m) => sum + m.documentation, 0) / allMetrics.length,
      securityScore: allMetrics.reduce((sum, m) => sum + m.securityScore, 0) / allMetrics.length,
    };

    const overall =
      (averages.testCoverage +
        averages.codeQuality +
        averages.documentation +
        averages.securityScore) /
      4;

    return { overall, ...averages };
  }

  private generateQualityRecommendations(project: Project): string[] {
    const recommendations: string[] = [];
    const metrics = this.calculateQualityMetrics(project);

    if (metrics.testCoverage < 80) {
      recommendations.push('Increase test coverage to at least 80%');
    }
    if (metrics.codeQuality < 70) {
      recommendations.push('Improve code quality through refactoring and code reviews');
    }
    if (metrics.documentation < 60) {
      recommendations.push('Enhance documentation coverage for better maintainability');
    }
    if (metrics.securityScore < 85) {
      recommendations.push(
        'Address security vulnerabilities and implement security best practices',
      );
    }

    return recommendations;
  }

  private getAllRisks(project: Project): ProjectRisk[] {
    return project.phases.flatMap((p) => p.risks);
  }

  private generateRiskMatrix(risks: ProjectRisk[]): any {
    const matrix = {
      low: { low: 0, medium: 0, high: 0 },
      medium: { low: 0, medium: 0, high: 0 },
      high: { low: 0, medium: 0, high: 0 },
    };

    for (const risk of risks) {
      if (risk.status === 'open') {
        matrix[risk.probability][risk.impact]++;
      }
    }

    return matrix;
  }

  private generateRiskMitigation(risks: ProjectRisk[]): any {
    const openRisks = risks.filter((r) => r.status === 'open');
    const highPriorityRisks = openRisks.filter(
      (r) =>
        (r.probability === 'high' && r.impact === 'high') ||
        (r.probability === 'high' && r.impact === 'medium') ||
        (r.probability === 'medium' && r.impact === 'high'),
    );

    return {
      totalRisks: risks.length,
      openRisks: openRisks.length,
      highPriorityRisks: highPriorityRisks.length,
      mitigationActions: highPriorityRisks.map((r) => ({
        risk: r.description,
        mitigation: r.mitigation,
        assignedTo: r.assignedTo,
      })),
    };
  }

  private getTotalResources(project: Project): number {
    return project.phases.reduce((sum, phase) => sum + phase.resources.length, 0);
  }

  private calculateResourceAllocation(project: Project): any {
    const allocation: Record<string, number> = {};

    for (const phase of project.phases) {
      for (const resource of phase.resources) {
        allocation[resource.type] = (allocation[resource.type] || 0) + 1;
      }
    }

    return allocation;
  }

  private calculateResourceUtilization(project: Project): any {
    const utilization: Record<string, number> = {};

    for (const phase of project.phases) {
      for (const resource of phase.resources) {
        utilization[resource.type] = (utilization[resource.type] || 0) + resource.availability;
      }
    }

    return utilization;
  }

  private calculateCapacity(project: Project): any {
    const teamSize = project.collaboration.teamMembers.length;
    const totalAvailability = project.collaboration.teamMembers.reduce(
      (sum, member) => sum + member.availability,
      0,
    );

    return {
      teamSize,
      totalAvailability,
      averageAvailability: teamSize > 0 ? totalAvailability / teamSize : 0,
    };
  }

  private calculateComplianceStatus(project: Project): any {
    const requirements = project.complianceRequirements;
    const total = requirements.length;
    const compliant = requirements.filter((r) => r.status === 'compliant').length;
    const inProgress = requirements.filter((r) => r.status === 'in-progress').length;
    const nonCompliant = requirements.filter((r) => r.status === 'non-compliant').length;

    return {
      total,
      compliant,
      inProgress,
      nonCompliant,
      compliancePercentage: total > 0 ? (compliant / total) * 100 : 0,
    };
  }

  private identifyComplianceGaps(project: Project): ComplianceRequirement[] {
    return project.complianceRequirements.filter(
      (r) => r.status === 'not-started' || r.status === 'non-compliant',
    );
  }

  private generateComplianceRecommendations(project: Project): string[] {
    const gaps = this.identifyComplianceGaps(project);
    const recommendations: string[] = [];

    for (const gap of gaps) {
      recommendations.push(
        `Address ${gap.framework} requirement: ${gap.name} (Due: ${gap.dueDate.toLocaleDateString()})`,
      );
    }

    return recommendations;
  }
}
