/**
 * ${VOCAB.brain} - Self-Evolution Helper Library
 * 
 * This module provides convenient functions for the Ghost to
 * evolve, learn, and modify its own behavior.
 */

import { prisma } from '@/lib/db';
import { VOCAB } from '@/lib/white-label/constants';

const EVOLVE_API = '/api/gfs/evolve';

// Types
export interface Memory {
  category: string;
  key: string;
  value: unknown;
  confidence?: number;
  source?: string;
}

export interface Rule {
  name: string;
  trigger: string;
  triggerType: 'regex' | 'keyword' | 'schedule' | 'event' | 'condition';
  action: unknown;
  priority?: number;
}

export interface Capability {
  name: string;
  type: 'command' | 'handler' | 'integration' | 'workflow';
  code?: string;
  config?: unknown;
}

// ============================================
// MEMORY OPERATIONS
// ============================================

export async function remember(
  category: string,
  key: string,
  value: unknown,
  options: { confidence?: number; source?: string; reason?: string } = {}
): Promise<boolean> {
  try {
    const existing = await prisma.ghostMemory.findUnique({
      where: { category_key: { category, key } },
    });

    if (existing) {
      await prisma.ghostMemory.update({
        where: { id: existing.id },
        data: {
          value: value as any,
          confidence: options.confidence ?? existing.confidence,
          source: options.source ?? existing.source,
        },
      });
    } else {
      await prisma.ghostMemory.create({
        data: {
          category,
          key,
          value: value as any,
          confidence: options.confidence ?? 1.0,
          source: options.source,
        },
      });
    }

    // Log evolution
    await prisma.ghostEvolution.create({
      data: {
        type: existing ? 'memory_update' : 'memory_add',
        description: `${existing ? 'Updated' : 'Learned'}: ${category}/${key}`,
        before: existing?.value as any ?? null,
        after: value as any,
        reason: options.reason,
        confidence: options.confidence ?? 1.0,
      },
    });

    return true;
  } catch (error) {
    console.error('remember error:', error);
    return false;
  }
}

export async function recall(
  category: string,
  key: string
): Promise<unknown | null> {
  try {
    const memory = await prisma.ghostMemory.findUnique({
      where: { category_key: { category, key } },
    });

    if (memory) {
      // Update usage
      await prisma.ghostMemory.update({
        where: { id: memory.id },
        data: {
          usageCount: memory.usageCount + 1,
          lastUsed: new Date(),
        },
      });
      return memory.value;
    }

    return null;
  } catch (error) {
    console.error('recall error:', error);
    return null;
  }
}

export async function forget(category: string, key: string): Promise<boolean> {
  try {
    const existing = await prisma.ghostMemory.findUnique({
      where: { category_key: { category, key } },
    });

    if (existing) {
      await prisma.ghostMemory.delete({ where: { id: existing.id } });
      
      await prisma.ghostEvolution.create({
        data: {
          type: 'memory_delete',
          description: `Forgot: ${category}/${key}`,
          before: existing.value as any,
          after: null as any,
          reason: 'Memory deletion requested',
        },
      });
    }

    return true;
  } catch (error) {
    console.error('forget error:', error);
    return false;
  }
}

export async function recallAll(category: string): Promise<Array<{ key: string; value: unknown }>> {
  try {
    const memories = await prisma.ghostMemory.findMany({
      where: { category },
      orderBy: { usageCount: 'desc' },
    });

    return memories.map((m: any) => ({ key: m.key, value: m.value }));
  } catch (error) {
    console.error('recallAll error:', error);
    return [];
  }
}

// ============================================
// USER CONTEXT
// ============================================

export async function rememberUserPreference(
  userId: string,
  preference: string,
  value: unknown
): Promise<boolean> {
  return remember('user_preference', `${userId}:${preference}`, value, {
    source: 'user_interaction',
  });
}

export async function getUserPreference(
  userId: string,
  preference: string
): Promise<unknown | null> {
  return recall('user_preference', `${userId}:${preference}`);
}

// ============================================
// PATTERN LEARNING
// ============================================

export async function learnPattern(
  patternName: string,
  pattern: unknown,
  confidence: number = 0.8
): Promise<boolean> {
  return remember('pattern', patternName, pattern, {
    confidence,
    source: 'pattern_detection',
  });
}

export async function getPattern(patternName: string): Promise<unknown | null> {
  return recall('pattern', patternName);
}

// ============================================
// INSIGHTS
// ============================================

export async function recordInsight(
  topic: string,
  insight: string,
  confidence: number = 0.8
): Promise<boolean> {
  try {
    await prisma.ghostMemory.upsert({
      where: { category_key: { category: 'insight', key: topic } },
      create: {
        category: 'insight',
        key: topic,
        value: { insight, timestamp: new Date().toISOString() } as any,
        confidence,
        source: 'self-reflection',
      },
      update: {
        value: { insight, timestamp: new Date().toISOString() } as any,
        confidence,
      },
    });

    await prisma.ghostEvolution.create({
      data: {
        type: 'insight',
        description: `Insight: ${topic}`,
        after: { topic, insight } as any,
        confidence,
      },
    });

    return true;
  } catch (error) {
    console.error('recordInsight error:', error);
    return false;
  }
}

// ============================================
// RULES
// ============================================

export async function addRule(rule: Rule): Promise<boolean> {
  try {
    await prisma.ghostRule.create({
      data: {
        name: rule.name,
        trigger: rule.trigger,
        triggerType: rule.triggerType,
        action: rule.action as any,
        priority: rule.priority ?? 0,
      },
    });

    await prisma.ghostEvolution.create({
      data: {
        type: 'rule_add',
        description: `Added rule: ${rule.name}`,
        after: rule as any,
      },
    });

    return true;
  } catch (error) {
    console.error('addRule error:', error);
    return false;
  }
}

export async function getActiveRules(): Promise<Rule[]> {
  try {
    const rules = await prisma.ghostRule.findMany({
      where: { isActive: true },
      orderBy: { priority: 'desc' },
    });

    return rules.map((r: any) => ({
      name: r.name,
      trigger: r.trigger,
      triggerType: r.triggerType as Rule['triggerType'],
      action: r.action,
      priority: r.priority,
    }));
  } catch (error) {
    console.error('getActiveRules error:', error);
    return [];
  }
}

// ============================================
// EVOLUTION HISTORY
// ============================================

export async function getEvolutionHistory(limit: number = 50) {
  try {
    return await prisma.ghostEvolution.findMany({
      take: limit,
      orderBy: { createdAt: 'desc' },
    });
  } catch (error) {
    console.error('getEvolutionHistory error:', error);
    return [];
  }
}

export async function getSelfStats() {
  try {
    const [memories, rules, capabilities, evolutions] = await Promise.all([
      prisma.ghostMemory.count(),
      prisma.ghostRule.count({ where: { isActive: true } }),
      prisma.ghostCapability.count({ where: { isActive: true } }),
      prisma.ghostEvolution.count(),
    ]);

    return {
      totalMemories: memories,
      activeRules: rules,
      activeCapabilities: capabilities,
      totalEvolutions: evolutions,
    };
  } catch (error) {
    console.error('getSelfStats error:', error);
    return null;
  }
}
