/**
 * Well-Architected Framework & Industry Cloud Service
 * Comprehensive WAF implementation with industry-specific controls
 */

import { getDb } from '../db/index.js'
import { logger } from '../lib/logger.js'
import { Context } from '../types/context.js'

export enum IndustryType {
  FINANCIAL = 'FINANCIAL',
  TELECOMMUNICATIONS = 'TELECOMMUNICATIONS',
  HEALTHCARE = 'HEALTHCARE',
  GOVERNMENT = 'GOVERNMENT',
  MANUFACTURING = 'MANUFACTURING',
  RETAIL = 'RETAIL',
  EDUCATION = 'EDUCATION',
}

export interface IndustryControl {
  id: string
  industry: IndustryType
  pillar: string
  controlCode: string
  name: string
  description: string
  complianceFrameworks: string[]
  requirements: string[]
}

export interface WAFAssessment {
  id: string
  resourceId: string
  industry: IndustryType
  pillarScores: Record<string, number>
  findings: WAFFinding[]
  risks: WAFRisk[]
  recommendations: WAFRecommendation[]
  assessedAt: Date
}

export interface WAFFinding {
  id: string
  controlId: string
  resourceId: string
  status: 'PASS' | 'FAIL' | 'WARNING'
  severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
  message: string
  recommendation: string
}

export interface WAFRisk {
  id: string
  resourceId: string
  pillar: string
  severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
  title: string
  description: string
  mitigation: string
}

export interface WAFRecommendation {
  id: string
  resourceId: string
  pillar: string
  priority: 'LOW' | 'MEDIUM' | 'HIGH'
  title: string
  description: string
  impact: string
  effort: 'LOW' | 'MEDIUM' | 'HIGH'
}

class WellArchitectedIndustryService {
  /**
   * Get industry-specific controls
   */
  async getIndustryControls(
    context: Context,
    industry: IndustryType
  ): Promise<IndustryControl[]> {
    const db = getDb()
    const result = await db.query(
      `SELECT * FROM industry_controls WHERE industry = $1 ORDER BY pillar, control_code`,
      [industry]
    )
    return result.rows.map(this.mapIndustryControl)
  }

  /**
   * Assess resource against WAF for industry
   */
  async assessResource(
    context: Context,
    resourceId: string,
    industry: IndustryType
  ): Promise<WAFAssessment> {
    logger.info('Assessing resource against WAF', { resourceId, industry })

    const controls = await this.getIndustryControls(context, industry)
    const findings: WAFFinding[] = []
    const risks: WAFRisk[] = []
    const pillarScores: Record<string, number> = {}

    // Assess each control
    for (const control of controls) {
      const finding = await this.assessControl(context, resourceId, control)
      findings.push(finding)

      // Update pillar score
      if (!pillarScores[control.pillar]) {
        pillarScores[control.pillar] = 100
      }

      if (finding.status === 'FAIL') {
        pillarScores[control.pillar] -= finding.severity === 'CRITICAL' ? 20 : finding.severity === 'HIGH' ? 10 : 5
      } else if (finding.status === 'WARNING') {
        pillarScores[control.pillar] -= 2
      }
    }

    // Generate risks
    const failedFindings = findings.filter((f) => f.status === 'FAIL')
    for (const finding of failedFindings) {
      risks.push({
        id: `risk-${finding.id}`,
        resourceId,
        pillar: controls.find((c) => c.id === finding.controlId)?.pillar || '',
        severity: finding.severity,
        title: finding.message,
        description: finding.message,
        mitigation: finding.recommendation,
      })
    }

    // Generate recommendations
    const recommendations = await this.generateRecommendations(
      context,
      resourceId,
      findings,
      industry
    )

    // Store assessment
    const db = getDb()
    const result = await db.query(
      `INSERT INTO waf_assessments (
        resource_id, industry, pillar_scores, findings, risks, recommendations
      ) VALUES ($1, $2, $3, $4, $5, $6)
      RETURNING *`,
      [
        resourceId,
        industry,
        JSON.stringify(pillarScores),
        JSON.stringify(findings),
        JSON.stringify(risks),
        JSON.stringify(recommendations),
      ]
    )

    return this.mapAssessment(result.rows[0])
  }

  /**
   * Assess individual control
   */
  private async assessControl(
    context: Context,
    resourceId: string,
    control: IndustryControl
  ): Promise<WAFFinding> {
    // In production, this would evaluate the control against the resource
    // For now, return a placeholder
    return {
      id: `finding-${control.id}-${resourceId}`,
      controlId: control.id,
      resourceId,
      status: 'PASS',
      severity: 'LOW',
      message: `Control ${control.controlCode} assessed`,
      recommendation: '',
    }
  }

  /**
   * Generate recommendations
   */
  private async generateRecommendations(
    context: Context,
    resourceId: string,
    findings: WAFFinding[],
    industry: IndustryType
  ): Promise<WAFRecommendation[]> {
    const recommendations: WAFRecommendation[] = []

    for (const finding of findings.filter((f) => f.status === 'FAIL')) {
      recommendations.push({
        id: `rec-${finding.id}`,
        resourceId,
        pillar: '', // Would be determined from control
        priority: finding.severity === 'CRITICAL' ? 'HIGH' : finding.severity === 'HIGH' ? 'MEDIUM' : 'LOW',
        title: `Fix ${finding.message}`,
        description: finding.recommendation,
        impact: 'Improves WAF score',
        effort: 'MEDIUM',
      })
    }

    return recommendations
  }

  // Mapper functions
  private mapIndustryControl(row: any): IndustryControl {
    return {
      id: row.id,
      industry: row.industry as IndustryType,
      pillar: row.pillar,
      controlCode: row.control_code,
      name: row.name,
      description: row.description,
      complianceFrameworks: row.compliance_frameworks || [],
      requirements: row.requirements || [],
    }
  }

  private mapAssessment(row: any): WAFAssessment {
    return {
      id: row.id,
      resourceId: row.resource_id,
      industry: row.industry as IndustryType,
      pillarScores: row.pillar_scores || {},
      findings: row.findings || [],
      risks: row.risks || [],
      recommendations: row.recommendations || [],
      assessedAt: row.assessed_at,
    }
  }
}

export const wellArchitectedIndustryService = new WellArchitectedIndustryService()

