/**
 * Self-Modification System
 * Proposes and implements system improvements
 */

import prisma from '@/lib/db';
import { SelfModificationProposal, PatternData } from './types';
import { checkForSignificantPatterns } from './pattern-engine';

export async function generateProposalsFromPatterns(): Promise<string[]> {
  const significantPatterns = await checkForSignificantPatterns();
  const proposalIds: string[] = [];

  for (const pattern of significantPatterns) {
    const proposal = await createProposalFromPattern(pattern);
    if (proposal) {
      proposalIds.push(proposal);
    }
  }

  return proposalIds;
}

async function createProposalFromPattern(pattern: PatternData): Promise<string | null> {
  const existing = await prisma.selfModProposal.findFirst({
    where: {
      sourcePatternId: `${pattern.patternType}:${pattern.patternKey}`,
      status: 'pending',
    },
  });

  if (existing) return null;

  const proposal: SelfModificationProposal = {
    proposalType: 'config_change',
    title: `Update ${pattern.patternType} for ${pattern.patternKey}`,
    description: `Pattern detected with ${(pattern.confidence * 100).toFixed(0)}% confidence.`,
    rationale: `Based on ${pattern.sampleSize} observations.`,
    targetSystem: pattern.patternType,
    currentState: {},
    proposedState: pattern.value as Record<string, unknown>,
    riskLevel: 'low',
    confidence: pattern.confidence,
  };

  const created = await prisma.selfModProposal.create({
    data: {
      sourcePatternId: `${pattern.patternType}:${pattern.patternKey}`,
      proposalType: proposal.proposalType,
      title: proposal.title,
      description: proposal.description,
      rationale: proposal.rationale,
      targetSystem: proposal.targetSystem,
      currentState: JSON.parse(JSON.stringify(proposal.currentState)),
      proposedState: JSON.parse(JSON.stringify(proposal.proposedState)),
      riskLevel: proposal.riskLevel,
      confidence: proposal.confidence,
    },
  });

  return created.id;
}

export async function approveProposal(proposalId: string, reviewedBy: string): Promise<boolean> {
  const proposal = await prisma.selfModProposal.findUnique({ where: { id: proposalId } });
  if (!proposal || proposal.status !== 'pending') return false;

  await prisma.selfModProposal.update({
    where: { id: proposalId },
    data: {
      status: 'implemented',
      reviewedBy,
      reviewedAt: new Date(),
      implementedAt: new Date(),
    },
  });

  return true;
}

export async function rejectProposal(proposalId: string, reviewedBy: string): Promise<void> {
  await prisma.selfModProposal.update({
    where: { id: proposalId },
    data: {
      status: 'rejected',
      reviewedBy,
      reviewedAt: new Date(),
    },
  });
}

export async function getPendingProposals(limit = 20) {
  return prisma.selfModProposal.findMany({
    where: { status: 'pending' },
    orderBy: [
      { riskLevel: 'asc' },
      { confidence: 'desc' },
      { createdAt: 'asc' },
    ],
    take: limit,
  });
}

export async function getProposalStats() {
  const [pending, approved, rejected, implemented] = await Promise.all([
    prisma.selfModProposal.count({ where: { status: 'pending' } }),
    prisma.selfModProposal.count({ where: { status: 'approved' } }),
    prisma.selfModProposal.count({ where: { status: 'rejected' } }),
    prisma.selfModProposal.count({ where: { status: 'implemented' } }),
  ]);

  return { pending, approved, rejected, implemented };
}
