import { getDb } from '../db'
import { Context } from '../types/context'
import { GraphQLError } from 'graphql'
import { logger } from '../lib/logger'

export interface OptimizationRecommendation {
  id: string
  type: 'COST' | 'PERFORMANCE' | 'SECURITY'
  title: string
  description: string
  potentialSavings: number
  impact: 'LOW' | 'MEDIUM' | 'HIGH'
  effort: 'LOW' | 'MEDIUM' | 'HIGH'
  resourceId?: string
  priority: number
}

/**
 * AI-Powered Optimization Engine
 * Analyzes resources and provides intelligent recommendations
 */
export async function getOptimizationRecommendations(
  context: Context,
  tenantId?: string
): Promise<OptimizationRecommendation[]> {
  if (!context.user) {
    throw new GraphQLError('Authentication required', {
      extensions: { code: 'UNAUTHENTICATED' },
    })
  }

  const db = getDb()
  const recommendations: OptimizationRecommendation[] = []

  // Get resources for analysis
  const resourcesResult = await db.query(`
    SELECT r.*, ri.cost_per_hour, ri.utilization
    FROM resources r
    LEFT JOIN resource_inventory ri ON ri.resource_id = r.id
    WHERE r.tenant_id = $1 OR $1 IS NULL
    LIMIT 100
  `, [tenantId || null])

  const resources = resourcesResult.rows

  // Cost Optimization Recommendations
  for (const resource of resources) {
    // Idle resources
    if (resource.utilization < 10 && resource.cost_per_hour > 0) {
      const monthlySavings = resource.cost_per_hour * 24 * 30 * 0.9 // 90% savings if stopped
      recommendations.push({
        id: `cost-idle-${resource.id}`,
        type: 'COST',
        title: `Stop Idle Resource: ${resource.name}`,
        description: `Resource ${resource.name} has low utilization (${resource.utilization}%) but is incurring costs. Consider stopping it to save approximately $${monthlySavings.toFixed(2)}/month.`,
        potentialSavings: monthlySavings,
        impact: monthlySavings > 100 ? 'HIGH' : monthlySavings > 50 ? 'MEDIUM' : 'LOW',
        effort: 'LOW',
        resourceId: resource.id,
        priority: monthlySavings,
      })
    }

    // Over-provisioned resources
    if (resource.utilization < 30 && resource.cost_per_hour > 0) {
      const savings = resource.cost_per_hour * 0.5 * 24 * 30 // 50% savings if downsized
      recommendations.push({
        id: `cost-downsize-${resource.id}`,
        type: 'COST',
        title: `Downsize Resource: ${resource.name}`,
        description: `Resource ${resource.name} is over-provisioned (${resource.utilization}% utilization). Consider downsizing to save approximately $${savings.toFixed(2)}/month.`,
        potentialSavings: savings,
        impact: savings > 100 ? 'HIGH' : savings > 50 ? 'MEDIUM' : 'LOW',
        effort: 'MEDIUM',
        resourceId: resource.id,
        priority: savings,
      })
    }
  }

  // Performance Optimization Recommendations
  for (const resource of resources) {
    // High utilization resources
    if (resource.utilization > 90) {
      recommendations.push({
        id: `perf-scale-${resource.id}`,
        type: 'PERFORMANCE',
        title: `Scale Up Resource: ${resource.name}`,
        description: `Resource ${resource.name} is running at ${resource.utilization}% utilization. Consider scaling up to prevent performance degradation.`,
        potentialSavings: 0,
        impact: 'HIGH',
        effort: 'LOW',
        resourceId: resource.id,
        priority: 1000 - resource.utilization, // Higher priority for higher utilization
      })
    }

    // Low performance resources
    if (resource.utilization > 50 && resource.utilization < 70) {
      const avgResponseTime = resource.metadata?.avg_response_time || 0
      if (avgResponseTime > 1000) {
        recommendations.push({
          id: `perf-optimize-${resource.id}`,
          type: 'PERFORMANCE',
          title: `Optimize Resource: ${resource.name}`,
          description: `Resource ${resource.name} has high response time (${avgResponseTime}ms). Consider optimization to improve performance.`,
          potentialSavings: 0,
          impact: 'MEDIUM',
          effort: 'MEDIUM',
          resourceId: resource.id,
          priority: 500,
        })
      }
    }
  }

  // Security Recommendations
  const securityResult = await db.query(`
    SELECT COUNT(*) as count
    FROM policy_violations
    WHERE status = 'OPEN' AND severity IN ('HIGH', 'CRITICAL')
  `)

  const criticalViolations = parseInt(securityResult.rows[0]?.count) || 0

  if (criticalViolations > 0) {
    recommendations.push({
      id: 'security-violations',
      type: 'SECURITY',
      title: `Resolve ${criticalViolations} Critical Security Violations`,
      description: `You have ${criticalViolations} open security violations that need immediate attention. Review and resolve them to improve your security posture.`,
      potentialSavings: 0,
      impact: 'HIGH',
      effort: 'MEDIUM',
      priority: 2000,
    })
  }

  // Check for resources without encryption
  const unencryptedResult = await db.query(`
    SELECT COUNT(*) as count
    FROM resources r
    WHERE r.metadata->>'encryption' IS NULL OR r.metadata->>'encryption' = 'false'
  `)

  const unencryptedCount = parseInt(unencryptedResult.rows[0]?.count) || 0

  if (unencryptedCount > 0) {
    recommendations.push({
      id: 'security-encryption',
      type: 'SECURITY',
      title: `Enable Encryption for ${unencryptedCount} Resources`,
      description: `${unencryptedCount} resources are not encrypted. Enable encryption to protect sensitive data.`,
      potentialSavings: 0,
      impact: 'HIGH',
      effort: 'LOW',
      priority: 1500,
    })
  }

  // Sort by priority (highest first)
  recommendations.sort((a, b) => b.priority - a.priority)

  return recommendations.slice(0, 10) // Return top 10 recommendations
}

/**
 * Get cost optimization recommendations specifically
 */
export async function getCostOptimizationRecommendations(
  context: Context,
  tenantId: string
): Promise<OptimizationRecommendation[]> {
  const all = await getOptimizationRecommendations(context, tenantId)
  return all.filter(r => r.type === 'COST')
}

/**
 * Get performance optimization recommendations
 */
export async function getPerformanceRecommendations(
  context: Context,
  tenantId?: string
): Promise<OptimizationRecommendation[]> {
  const all = await getOptimizationRecommendations(context, tenantId)
  return all.filter(r => r.type === 'PERFORMANCE')
}

/**
 * Get security recommendations
 */
export async function getSecurityRecommendations(
  context: Context,
  tenantId?: string
): Promise<OptimizationRecommendation[]> {
  const all = await getOptimizationRecommendations(context, tenantId)
  return all.filter(r => r.type === 'SECURITY')
}

