/**
 * Project Context Builder for Chat
 * 
 * Loads project state from Firestore and AlloyDB vector memory,
 * building a compact context object for LLM consumption.
 */

import { query } from '@/lib/db-postgres';
import { retrieveRelevantChunks } from '@/lib/server/vector-memory';
import { embedText } from '@/lib/ai/embeddings';
import {
  summarizeKnowledgeItems,
  summarizeExtractions,
} from '@/lib/server/chat-mode-resolver';
import type { ChatMode } from '@/lib/ai/chat-modes';
import type { ProjectPhaseData, ProjectPhaseScores } from '@/lib/types/project-artifacts';
import type { PhaseHandoff } from '@/lib/types/phase-handoff';
import { formatCreationKickoffForPrompt } from "@/lib/server/creation-kickoff-prompt";

/**
 * Compact project context for LLM
 */
export interface ProjectChatContext {
  /** Basic project info */
  project: {
    id: string;
    name: string;
    currentPhase: string;
    phaseStatus: string;
    githubRepo?: string | null;
    githubRepoUrl?: string | null;
    extensionLinked?: boolean;
    visionAnswers?: {
      q1?: string;
      q2?: string;
      q3?: string;
      updatedAt?: string;
    };
    /** Gitea monorepo */
    giteaRepo?: string | null;
    giteaRepoUrl?: string | null;
    /** Turborepo apps */
    apps?: Array<{
      name: string;
      path: string;
      domain?: string | null;
      coolifyServiceUuid?: string | null;
    }>;
  };

  /** Phase-specific artifacts */
  phaseData: {
    canonicalProductModel?: any;
    mvpPlan?: any;
    marketingPlan?: any;
  };

  /** Phase scores and progress */
  phaseScores: ProjectPhaseScores;

  /** Phase handoffs for smart transitions */
  phaseHandoffs: Partial<Record<'collector' | 'extraction' | 'vision' | 'mvp' | 'marketing', PhaseHandoff>>;

  /** Knowledge summary (counts, types) */
  knowledgeSummary: {
    totalCount: number;
    bySourceType: Record<string, number>;
    recentTitles: string[];
  };

  /** Extraction summary */
  extractionSummary: {
    totalCount: number;
    avgConfidence: number;
    avgCompletion: number;
  };

  /** Relevant chunks from vector search */
  retrievedChunks: {
    content: string;
    sourceType?: string | null;
    importance?: string | null;
    similarity: number;
  }[];

  /** Repository analysis (if GitHub connected) */
  repositoryAnalysis?: {
    repoFullName: string;
    totalFiles: number;
    directories: string[];
    keyFiles: string[];
    techStack: string[];
    readme: string | null;
    summary: string;
  } | null;

  /** Session history from linked Cursor sessions */
  sessionHistory: {
    totalSessions: number;
    messages: Array<{
      role: string;
      content: string;
      timestamp: string;
      sessionId?: string;
    }>;
  };

  /** Wizard kickoff — selections + optional seed document */
  creationKickoff: string | null;
}

/**
 * Build project context for a chat interaction
 * 
 * @param projectId - Firestore project ID
 * @param mode - Current chat mode
 * @param userMessage - User's message (used for vector retrieval)
 * @param options - Context building options
 * @returns Compact context object
 */
export async function buildProjectContextForChat(
  projectId: string,
  mode: ChatMode,
  userMessage: string,
  options: {
    retrievalLimit?: number;
    includeVectorSearch?: boolean;
    includeGitHubAnalysis?: boolean;
  } = {}
): Promise<ProjectChatContext> {
  const {
    retrievalLimit = 10,
    includeVectorSearch = true,
    includeGitHubAnalysis = true,
  } = options;

  try {
    // Load project from Postgres
    const projectRows = await query<{ data: any }>(
      `SELECT data FROM fs_projects WHERE id = $1 LIMIT 1`,
      [projectId]
    );
    if (projectRows.length === 0) {
      throw new Error(`Project ${projectId} not found`);
    }

    const projectData = projectRows[0].data ?? {};

    // Load summaries in parallel
    const [knowledgeSummary, extractionSummary] = await Promise.all([
      summarizeKnowledgeItems(projectId),
      summarizeExtractions(projectId),
    ]);

    // Vector retrieval
    let retrievedChunks: ProjectChatContext['retrievedChunks'] = [];
    
    // extraction_review_mode does NOT load documents - it reviews extraction results
    // Normal vector search for modes that need it
    if (includeVectorSearch && mode !== 'collector_mode' && mode !== 'extraction_review_mode' && userMessage.trim().length > 0) {
      try {
        const queryEmbedding = await embedText(userMessage);
        const chunks = await retrieveRelevantChunks(projectId, queryEmbedding, {
          limit: retrievalLimit,
          minSimilarity: 0.7, // Only include reasonably relevant chunks
        });

        retrievedChunks = chunks.map((chunk) => ({
          content: chunk.content,
          sourceType: chunk.sourceType,
          importance: chunk.importance,
          similarity: chunk.similarity,
        }));

        console.log(
          `[Chat Context] Retrieved ${retrievedChunks.length} chunks for project ${projectId}`
        );
      } catch (vectorError) {
        console.error('[Chat Context] Vector retrieval failed:', vectorError);
        // Continue without vector results
      }
    }

    // GitHub repository analysis
    let repositoryAnalysis = null;
    if (includeGitHubAnalysis && projectData.githubRepo && projectData.userId) {
      try {
        const { analyzeGitHubRepository } = await import('@/lib/server/github-analyzer');
        repositoryAnalysis = await analyzeGitHubRepository(
          projectData.userId,
          projectData.githubRepo,
          projectData.githubDefaultBranch || 'main'
        );
      } catch (githubError) {
        console.error('[Chat Context] GitHub analysis failed:', githubError);
        // Continue without GitHub analysis
      }
    }

    // Fetch linked Cursor session history
    let sessionHistory = {
      totalSessions: 0,
      messages: [] as Array<{
        role: string;
        content: string;
        timestamp: string;
        sessionId?: string;
      }>,
    };

    try {
      // Query sessions linked to this project from PostgreSQL
      const sessionRows = await query<{ id: string; data: any }>(
        `SELECT id, data FROM fs_sessions WHERE data->>'projectId' = $1 ORDER BY created_at ASC`,
        [projectId]
      );

      if (sessionRows.length > 0) {
        sessionHistory.totalSessions = sessionRows.length;

        const allMessages: Array<{
          role: string;
          content: string;
          timestamp: string;
          sessionId: string;
        }> = [];

        for (const row of sessionRows) {
          const conversation = row.data?.conversation || [];
          for (const msg of conversation) {
            if (msg.content && msg.content.trim()) {
              allMessages.push({
                role: msg.role || 'unknown',
                content: msg.content,
                timestamp: typeof msg.timestamp === 'string'
                  ? msg.timestamp
                  : new Date().toISOString(),
                sessionId: row.id,
              });
            }
          }
        }

        allMessages.sort((a, b) =>
          new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
        );

        sessionHistory.messages = allMessages;
        console.log(
          `[Chat Context] Loaded ${sessionHistory.totalSessions} sessions with ${allMessages.length} total messages for project ${projectId}`
        );
      } else {
        console.log(`[Chat Context] No linked sessions found for project ${projectId}`);
      }
    } catch (sessionError) {
      console.error('[Chat Context] Session history fetch failed:', sessionError);
      // Continue without session history
    }

    const creationKickoff = formatCreationKickoffForPrompt(
      projectData as Record<string, unknown>,
    );

    // Build context object
    const context: ProjectChatContext = {
      project: {
        id: projectId,
        name: projectData.name ?? 'Unnamed Project',
        currentPhase: projectData.currentPhase ?? 'collector',
        phaseStatus: projectData.phaseStatus ?? 'not_started',
        githubRepo: projectData.githubRepo ?? null,
        githubRepoUrl: projectData.githubRepoUrl ?? null,
        extensionLinked: projectData.extensionLinked ?? false,
        visionAnswers: projectData.visionAnswers ?? {},
        giteaRepo: projectData.giteaRepo ?? null,
        giteaRepoUrl: projectData.giteaRepoUrl ?? null,
        apps: projectData.apps ?? [],
      },
      phaseData: {
        canonicalProductModel: projectData.phaseData?.canonicalProductModel ?? null,
        mvpPlan: projectData.phaseData?.mvpPlan ?? null,
        marketingPlan: projectData.phaseData?.marketingPlan ?? null,
      },
      phaseScores: projectData.phaseScores ?? {},
      phaseHandoffs: projectData.phaseData?.phaseHandoffs ?? {},
      knowledgeSummary,
      extractionSummary,
      retrievedChunks,
      repositoryAnalysis: repositoryAnalysis as any,
      sessionHistory, // ✅ Include session history in context
      creationKickoff,
    };

    return context;
  } catch (error) {
    console.error('[Chat Context] Failed to build context:', error);
    throw new Error(
      `Failed to build chat context: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

/**
 * Determine which artifacts were used in building the context
 * 
 * This helps the UI show what sources the AI is drawing from.
 */
export function determineArtifactsUsed(context: ProjectChatContext): string[] {
  const artifacts: string[] = [];

  if (context.phaseData.canonicalProductModel) {
    artifacts.push('Product Model');
  }

  if (context.phaseData.mvpPlan) {
    artifacts.push('MVP Plan');
  }

  if (context.phaseData.marketingPlan) {
    artifacts.push('Marketing Plan');
  }

  if (context.retrievedChunks.length > 0) {
    artifacts.push(`${context.retrievedChunks.length} Vector Chunks`);
  }

  if (context.repositoryAnalysis) {
    artifacts.push('GitHub Repo Analysis');
  }

  if (context.knowledgeSummary.totalCount > 0) {
    artifacts.push(`${context.knowledgeSummary.totalCount} Knowledge Items`);
  }

  if (context.extractionSummary.totalCount > 0) {
    artifacts.push(`${context.extractionSummary.totalCount} Extractions`);
  }

  if (context.sessionHistory.totalSessions > 0) {
    artifacts.push(`${context.sessionHistory.totalSessions} Cursor Sessions (${context.sessionHistory.messages.length} messages)`);
  }

  if (context.creationKickoff) {
    artifacts.push('Creation wizard kickoff');
  }

  return artifacts;
}

/**
 * Format project context as a string for LLM system prompt
 * 
 * Provides a human-readable summary of the context.
 */
export function formatContextForPrompt(context: ProjectChatContext): string {
  const sections: string[] = [];

  // Project info
  sections.push(`Project: ${context.project.name} (ID: ${context.project.id})`);
  sections.push(
    `Phase: ${context.project.currentPhase} (${context.project.phaseStatus})`
  );

  if (context.creationKickoff) {
    sections.push(`\n${context.creationKickoff}`);
  }

  // Monorepo info
  if (context.project.giteaRepo) {
    sections.push(`\n## Monorepo (Turborepo)`);
    sections.push(`Repository: ${context.project.giteaRepoUrl ?? context.project.giteaRepo}`);
    if (context.project.apps && context.project.apps.length > 0) {
      sections.push(`Apps:`);
      for (const app of context.project.apps) {
        const domain = app.domain ? ` → https://${app.domain}` : '';
        sections.push(`  • ${app.name} (${app.path})${domain}`);
      }
    }
  }

  // Knowledge summary
  if (context.knowledgeSummary.totalCount > 0) {
    sections.push(`\nKnowledge Items: ${context.knowledgeSummary.totalCount} total`);
    if (Object.keys(context.knowledgeSummary.bySourceType).length > 0) {
      sections.push(
        `  By type: ${JSON.stringify(context.knowledgeSummary.bySourceType)}`
      );
    }
  }

  // Extraction summary
  if (context.extractionSummary.totalCount > 0) {
    sections.push(
      `\nExtractions: ${context.extractionSummary.totalCount} analyzed (avg confidence: ${(context.extractionSummary.avgConfidence * 100).toFixed(1)}%)`
    );
  }

  // Retrieved chunks
  if (context.retrievedChunks.length > 0) {
    sections.push(`\nRelevant Context (vector search):`);
    context.retrievedChunks.slice(0, 3).forEach((chunk, i) => {
      sections.push(
        `  ${i + 1}. [${chunk.sourceType ?? 'unknown'}] (similarity: ${(chunk.similarity * 100).toFixed(1)}%)`
      );
      sections.push(`     ${chunk.content.substring(0, 150)}...`);
    });
  }

  // GitHub repo
  if (context.repositoryAnalysis) {
    sections.push(`\nGitHub Repository: ${context.repositoryAnalysis.repoFullName}`);
    sections.push(`  Files: ${context.repositoryAnalysis.totalFiles}`);
    sections.push(`  Tech: ${context.repositoryAnalysis.techStack.join(', ')}`);
  }

  // Phase handoffs
  const handoffs = Object.keys(context.phaseHandoffs);
  if (handoffs.length > 0) {
    sections.push(`\nPhase Handoffs: ${handoffs.join(', ')}`);
  }

  // Session history
  if (context.sessionHistory.totalSessions > 0) {
    sections.push(`\n## Cursor Session History (${context.sessionHistory.totalSessions} sessions, ${context.sessionHistory.messages.length} messages)`);
    sections.push(`This is your complete conversation history with the user from Cursor IDE, in chronological order.`);
    sections.push(`Use this to understand what has been built, discussed, and decided so far.\n`);
    
    // Include all messages chronologically
    context.sessionHistory.messages.forEach((msg, i) => {
      const timestamp = new Date(msg.timestamp).toLocaleString();
      sections.push(`[${timestamp}] ${msg.role}:`);
      sections.push(msg.content);
      sections.push(''); // Empty line between messages
    });
  }

  return sections.join('\n');
}

