import { config } from '../config/env';
import { logger } from '../utils/logger';
import { z } from 'zod';
import { CIMReview, cimReviewSchema } from './llmSchemas';

export interface LLMRequest {
  prompt: string;
  systemPrompt?: string;
  maxTokens?: number;
  temperature?: number;
  model?: string;
}

export interface LLMResponse {
  success: boolean;
  content: string;
  usage?: {
    promptTokens: number;
    completionTokens: number;
    totalTokens: number;
  } | undefined;
  error?: string;
}

export interface CIMAnalysisResult {
  success: boolean;
  jsonOutput?: CIMReview;
  error?: string;
  model: string;
  cost: number;
  inputTokens: number;
  outputTokens: number;
  validationIssues?: z.ZodIssue[];
}

class LLMService {
  private provider: string;
  private apiKey: string;
  private defaultModel: string;
  private maxTokens: number;
  private temperature: number;

  constructor() {
    this.provider = config.llm.provider;
    this.apiKey = this.provider === 'openai' 
      ? config.llm.openaiApiKey! 
      : config.llm.anthropicApiKey!;
    
    // Set the correct default model based on provider
    if (this.provider === 'anthropic') {
      this.defaultModel = 'claude-3-opus-20240229';
    } else {
      this.defaultModel = config.llm.model;
    }
    
    this.maxTokens = config.llm.maxTokens;
    this.temperature = config.llm.temperature;
  }

  /**
   * Process CIM document with intelligent model selection and self-correction
   */
  async processCIMDocument(text: string, template: string, analysis?: Record<string, any>): Promise<CIMAnalysisResult> {
    logger.info('Starting CIM document processing with LLM');
    
    const taskComplexity = this.determineTaskComplexity(text, analysis || {});
    const estimatedTokens = this.estimateTokenCount(text + template);
    const selectedModel = this.selectModel(taskComplexity, estimatedTokens);
    
    logger.info('Model selection completed', { taskComplexity, estimatedTokens, selectedModel });

    const isRefinement = analysis?.['refinementMode'] === true;
    const isOverview = analysis?.['overviewMode'] === true;
    const isSynthesis = analysis?.['synthesisMode'] === true;
    const sectionType = analysis?.['sectionType'] as string;
    
    let lastError: Error | null = null;
    
    for (let attempt = 1; attempt <= 3; attempt++) {
      try {
        logger.info(`LLM processing attempt ${attempt}/3`);
        
        let prompt: string;
        let systemPrompt: string;
        
        if (isOverview) {
          prompt = this.buildOverviewPrompt(text);
          systemPrompt = this.getOverviewSystemPrompt();
        } else if (isSynthesis) {
          prompt = this.buildSynthesisPrompt(text);
          systemPrompt = this.getSynthesisSystemPrompt();
        } else if (sectionType) {
          prompt = this.buildSectionPrompt(text, sectionType, analysis || {});
          systemPrompt = this.getSectionSystemPrompt(sectionType);
        } else if (isRefinement) {
          prompt = this.buildRefinementPrompt(text);
          systemPrompt = this.getRefinementSystemPrompt();
        } else {
          prompt = this.buildCIMPrompt(text, template, lastError ? lastError.message : undefined);
          systemPrompt = this.getCIMSystemPrompt();
        }
        
        const response = await this.callLLM({
          prompt,
          systemPrompt,
          model: selectedModel,
          maxTokens: config.llm.maxTokens,
          temperature: config.llm.temperature,
        });

        if (!response.success) {
          throw new Error('LLM processing failed');
        }

        const jsonOutput = this.extractJsonFromResponse(response.content);
        const validation = cimReviewSchema.safeParse(jsonOutput);

        if (validation.success) {
          logger.info(`CIM document processing completed successfully on attempt ${attempt}`);
          return {
            success: true,
            jsonOutput: validation.data,
            model: selectedModel,
            cost: this.estimateCost(estimatedTokens + response.content.length, selectedModel),
            inputTokens: estimatedTokens,
            outputTokens: response.content.length,
          };
        } else {
          lastError = new Error(`JSON validation failed: ${validation.error.errors.map(e => e.message).join(', ')}`);
          logger.warn(`LLM output validation failed on attempt ${attempt}`, { issues: validation.error.errors });
          if (attempt === 3) {
            return {
              success: false,
              error: 'Failed to generate valid JSON after 3 attempts.',
              model: selectedModel,
              cost: this.estimateCost(estimatedTokens, selectedModel),
              inputTokens: estimatedTokens,
              outputTokens: 0,
              validationIssues: validation.error.errors,
            };
          }
        }
      } catch (error) {
        lastError = error instanceof Error ? error : new Error('Unknown error');
        logger.error(`LLM processing attempt ${attempt} failed`, { error: lastError.message });
        if (attempt === 3) {
          throw lastError;
        }
      }
    }
    
    throw lastError || new Error('All LLM processing attempts failed');
  }

  /**
   * Call the appropriate LLM API
   */
  private async callLLM(request: LLMRequest): Promise<LLMResponse> {
    try {
      // Add a timeout wrapper to prevent hanging
      const timeoutPromise = new Promise<LLMResponse>((_, reject) => {
        setTimeout(() => reject(new Error('LLM call timeout after 3 minutes')), 180000);
      });

      const llmPromise = (async () => {
        if (this.provider === 'openai') {
          return await this.callOpenAI(request);
        } else if (this.provider === 'anthropic') {
          return await this.callAnthropic(request);
        } else {
          throw new Error(`Unsupported LLM provider: ${this.provider}`);
        }
      })();

      return await Promise.race([llmPromise, timeoutPromise]);
    } catch (error) {
      logger.error('LLM API call failed', error);
      return {
        success: false,
        content: '',
        error: error instanceof Error ? error.message : 'Unknown error',
      };
    }
  }

  /**
   * Call OpenAI API
   */
  private async callOpenAI(request: LLMRequest): Promise<LLMResponse> {
    const { default: OpenAI } = await import('openai');
    
    const openai = new OpenAI({
      apiKey: this.apiKey,
      timeout: 120000, // 2 minute timeout
    });

    const messages: any[] = [];
    
    if (request.systemPrompt) {
      messages.push({
        role: 'system',
        content: request.systemPrompt,
      });
    }

    messages.push({
      role: 'user',
      content: request.prompt,
    });

    const completion = await openai.chat.completions.create({
      model: request.model || this.defaultModel,
      messages,
      max_tokens: request.maxTokens || this.maxTokens,
      temperature: request.temperature || this.temperature,
    });

    const content = completion.choices[0]?.message?.content || '';
    const usage = completion.usage ? {
      promptTokens: completion.usage.prompt_tokens,
      completionTokens: completion.usage.completion_tokens,
      totalTokens: completion.usage.total_tokens,
    } : undefined;

    return {
      success: true,
      content,
      usage,
    };
  }

  /**
   * Call Anthropic API
   */
  private async callAnthropic(request: LLMRequest): Promise<LLMResponse> {
    try {
      const { default: Anthropic } = await import('@anthropic-ai/sdk');
      
      const anthropic = new Anthropic({
        apiKey: this.apiKey,
        timeout: 120000, // 2 minute timeout
      });

      const message = await anthropic.messages.create({
        model: request.model || this.defaultModel,
        max_tokens: request.maxTokens || this.maxTokens,
        temperature: request.temperature || this.temperature,
        system: request.systemPrompt || '',
        messages: [
          {
            role: 'user',
            content: request.prompt,
          },
        ],
      });

      const content = message.content[0]?.type === 'text' ? message.content[0].text : '';
      const usage = message.usage ? {
        promptTokens: message.usage.input_tokens,
        completionTokens: message.usage.output_tokens,
        totalTokens: message.usage.input_tokens + message.usage.output_tokens,
      } : undefined;

      return {
        success: true,
        content,
        usage,
      };
    } catch (error) {
      logger.error('Anthropic API error', error);
      throw new Error('Anthropic API error');
    }
  }

  /**
   * Get CIM system prompt
   */
  private getCIMSystemPrompt(): string {
    return `You are an expert investment analyst at BPCP (Blue Point Capital Partners) reviewing a Confidential Information Memorandum (CIM). Your task is to analyze CIM documents and return a comprehensive, structured JSON object that follows the BPCP CIM Review Template format EXACTLY.

CRITICAL REQUIREMENTS:
1. **JSON OUTPUT ONLY**: Your entire response MUST be a single, valid JSON object. Do not include any text or explanation before or after the JSON object.
2. **BPCP TEMPLATE FORMAT**: The JSON object MUST follow the BPCP CIM Review Template structure exactly as specified.
3. **COMPLETE ALL FIELDS**: You MUST provide a value for every field. Use "Not specified in CIM" for any information that is not available in the document.
4. **NO PLACEHOLDERS**: Do not use placeholders like "..." or "TBD". Use "Not specified in CIM" instead.
5. **PROFESSIONAL ANALYSIS**: The content should be high-quality and suitable for BPCP's investment committee.
6. **BPCP FOCUS**: Focus on companies in 5+MM EBITDA range in consumer and industrial end markets, with emphasis on M&A, technology & data usage, supply chain and human capital optimization.
7. **BPCP PREFERENCES**: BPCP prefers companies which are founder/family-owned and within driving distance of Cleveland and Charlotte.
8. **EXACT FIELD NAMES**: Use the exact field names and descriptions from the BPCP CIM Review Template.
9. **FINANCIAL DATA**: For financial metrics, use actual numbers if available, otherwise use "Not specified in CIM".
10. **VALID JSON**: Ensure your response is valid JSON that can be parsed without errors.

ANALYSIS QUALITY REQUIREMENTS:
- **Financial Precision**: Extract exact financial figures, percentages, and growth rates. Calculate CAGR where possible.
- **Competitive Intelligence**: Identify specific competitors, market positions, and competitive advantages.
- **Risk Assessment**: Evaluate both stated and implied risks, including operational, financial, and market risks.
- **Growth Drivers**: Identify specific revenue growth drivers, market expansion opportunities, and operational improvements.
- **Management Quality**: Assess management experience, track record, and post-transaction intentions.
- **Value Creation**: Identify specific value creation levers that align with BPCP's expertise.
- **Due Diligence Focus**: Highlight areas requiring deeper investigation and specific questions for management.

DOCUMENT ANALYSIS APPROACH:
- Read the entire document carefully, paying special attention to financial tables, charts, and appendices
- Cross-reference information across different sections for consistency
- Extract both explicit statements and implicit insights
- Focus on quantitative data while providing qualitative context
- Identify any inconsistencies or areas requiring clarification
- Consider industry context and market dynamics when evaluating opportunities and risks
`;
  }

  /**
   * Build CIM prompt from text and template, with optional error for self-correction
   */
  private buildCIMPrompt(text: string, _template: string, previousError?: string): string {
    const errorCorrection = previousError
      ? `
PREVIOUS ATTEMPT FAILED. The JSON you provided was invalid.
Here are the errors:
${previousError}

Please correct these errors and generate a new, valid JSON object. Pay close attention to the required structure and data types.
`
      : '';

    const jsonTemplate = `{
      "dealOverview": {
        "targetCompanyName": "Target Company Name",
        "industrySector": "Industry/Sector",
        "geography": "Geography (HQ & Key Operations)",
        "dealSource": "Deal Source",
        "transactionType": "Transaction Type",
        "dateCIMReceived": "Date CIM Received",
        "dateReviewed": "Date Reviewed",
        "reviewers": "Reviewer(s)",
        "cimPageCount": "CIM Page Count",
        "statedReasonForSale": "Stated Reason for Sale (if provided)",
        "employeeCount": "Number of employees (if stated in document)"
      },
      "businessDescription": {
        "coreOperationsSummary": "Core Operations Summary (3-5 sentences)",
        "keyProductsServices": "Key Products/Services & Revenue Mix (Est. % if available)",
        "uniqueValueProposition": "Unique Value Proposition (UVP) / Why Customers Buy",
        "customerBaseOverview": {
          "keyCustomerSegments": "Key Customer Segments/Types",
          "customerConcentrationRisk": "Customer Concentration Risk (Top 5 and/or Top 10 Customers as % Revenue - if stated/inferable)",
          "typicalContractLength": "Typical Contract Length / Recurring Revenue % (if applicable)"
        },
        "keySupplierOverview": {
          "dependenceConcentrationRisk": "Dependence/Concentration Risk"
        }
      },
      "marketIndustryAnalysis": {
        "estimatedMarketSize": "Estimated Market Size (TAM/SAM - if provided)",
        "estimatedMarketGrowthRate": "Estimated Market Growth Rate (% CAGR - Historical & Projected)",
        "keyIndustryTrends": "Key Industry Trends & Drivers (Tailwinds/Headwinds)",
        "competitiveLandscape": {
          "keyCompetitors": "Key Competitors Identified",
          "targetMarketPosition": "Target's Stated Market Position/Rank",
          "basisOfCompetition": "Basis of Competition"
        },
        "barriersToEntry": "Barriers to Entry / Competitive Moat (Stated/Inferred)"
      },
      "financialSummary": {
        "financials": {
          "fy3": {
            "revenue": "Revenue amount for FY-3",
            "revenueGrowth": "N/A (baseline year)",
            "grossProfit": "Gross profit amount for FY-3",
            "grossMargin": "Gross margin % for FY-3",
            "ebitda": "EBITDA amount for FY-3",
            "ebitdaMargin": "EBITDA margin % for FY-3"
          },
          "fy2": {
            "revenue": "Revenue amount for FY-2",
            "revenueGrowth": "Revenue growth % for FY-2",
            "grossProfit": "Gross profit amount for FY-2",
            "grossMargin": "Gross margin % for FY-2",
            "ebitda": "EBITDA amount for FY-2",
            "ebitdaMargin": "EBITDA margin % for FY-2"
          },
          "fy1": {
            "revenue": "Revenue amount for FY-1",
            "revenueGrowth": "Revenue growth % for FY-1",
            "grossProfit": "Gross profit amount for FY-1",
            "grossMargin": "Gross margin % for FY-1",
            "ebitda": "EBITDA amount for FY-1",
            "ebitdaMargin": "EBITDA margin % for FY-1"
          },
          "ltm": {
            "revenue": "Revenue amount for LTM",
            "revenueGrowth": "Revenue growth % for LTM",
            "grossProfit": "Gross profit amount for LTM",
            "grossMargin": "Gross margin % for LTM",
            "ebitda": "EBITDA amount for LTM",
            "ebitdaMargin": "EBITDA margin % for LTM"
          }
        },
        "qualityOfEarnings": "Quality of earnings/adjustments impression",
        "revenueGrowthDrivers": "Revenue growth drivers (stated)",
        "marginStabilityAnalysis": "Margin stability/trend analysis",
        "capitalExpenditures": "Capital expenditures (LTM % of revenue)",
        "workingCapitalIntensity": "Working capital intensity impression",
        "freeCashFlowQuality": "Free cash flow quality impression"
      },
      "managementTeamOverview": {
        "keyLeaders": "Key Leaders Identified (CEO, CFO, COO, Head of Sales, etc.)",
        "managementQualityAssessment": "Initial Assessment of Quality/Experience (Based on Bios)",
        "postTransactionIntentions": "Management's Stated Post-Transaction Role/Intentions (if mentioned)",
        "organizationalStructure": "Organizational Structure Overview (Impression)"
      },
      "preliminaryInvestmentThesis": {
        "keyAttractions": "Key Attractions / Strengths (Why Invest?)",
        "potentialRisks": "Potential Risks / Concerns (Why Not Invest?)",
        "valueCreationLevers": "Initial Value Creation Levers (How PE Adds Value)",
        "alignmentWithFundStrategy": "Alignment with Fund Strategy (BPCP is focused on companies in 5+MM EBITDA range in consumer and industrial end markets. M&A, increased technology & data usage, supply chain and human capital optimization are key value-levers. Also a preference companies which are founder / family-owned and within driving distance of Cleveland and Charlotte.)"
      },
      "keyQuestionsNextSteps": {
        "criticalQuestions": "Critical Questions Arising from CIM Review",
        "missingInformation": "Key Missing Information / Areas for Diligence Focus",
        "preliminaryRecommendation": "Preliminary Recommendation",
        "rationaleForRecommendation": "Rationale for Recommendation (Brief)",
        "proposedNextSteps": "Proposed Next Steps"
      }
    }`;

    return `Please analyze the following CIM document and generate a comprehensive JSON object based on the provided structure.

${errorCorrection}

DETAILED ANALYSIS INSTRUCTIONS:
1. **Financial Analysis**: Extract exact revenue, EBITDA, and margin figures. Calculate growth rates and trends. Note any adjustments or add-backs.
2. **Competitive Position**: Identify specific competitors, market share, and competitive advantages. Assess barriers to entry.
3. **Growth Opportunities**: Identify organic and inorganic growth drivers, market expansion potential, and operational improvements.
4. **Risk Assessment**: Evaluate customer concentration, supplier dependence, regulatory risks, and market risks.
5. **Management Quality**: Assess experience, track record, and post-transaction intentions. Evaluate organizational structure.
6. **Value Creation**: Identify specific levers for value creation through operational improvements, M&A, technology, and optimization.
7. **Due Diligence**: Highlight areas requiring deeper investigation and specific questions for management.

CIM Document Text:
${text}

Your response MUST be a single, valid JSON object that follows this exact structure. Do not include any other text.
JSON Structure to Follow:
\`\`\`json
${jsonTemplate}
\`\`\`

IMPORTANT: Replace all placeholder text with actual information from the CIM document. If information is not available, use "Not specified in CIM". Ensure all financial metrics are properly formatted as strings. Provide detailed, actionable insights suitable for investment decision-making.
`;
  }

  /**
   * Extract JSON from LLM response
   */
  private extractJsonFromResponse(content: string): any {
    try {
      // First, try to find JSON within ```json ... ```
      const jsonMatch = content.match(/```json\n([\s\S]*?)\n```/);
      if (jsonMatch && jsonMatch[1]) {
        return JSON.parse(jsonMatch[1]);
      }

      // Try to find JSON within ``` ... ```
      const codeBlockMatch = content.match(/```\n([\s\S]*?)\n```/);
      if (codeBlockMatch && codeBlockMatch[1]) {
        return JSON.parse(codeBlockMatch[1]);
      }

      // If that fails, try to find the largest valid JSON object
      const startIndex = content.indexOf('{');
      if (startIndex === -1) {
        throw new Error('No JSON object found in response');
      }

      // Try to find the complete JSON object by matching braces
      let braceCount = 0;
      let endIndex = -1;
      
      for (let i = startIndex; i < content.length; i++) {
        if (content[i] === '{') {
          braceCount++;
        } else if (content[i] === '}') {
          braceCount--;
          if (braceCount === 0) {
            endIndex = i;
            break;
          }
        }
      }

      if (endIndex === -1) {
        // If we can't find a complete JSON object, try to extract what we have
        // and attempt to complete it
        const partialJson = content.substring(startIndex);
        logger.warn('Attempting to recover from truncated JSON response', { 
          contentLength: content.length,
          partialJsonLength: partialJson.length 
        });
        
        // Try to find the last complete object or array
        const lastCompleteMatch = partialJson.match(/(\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\})/);
        if (lastCompleteMatch && lastCompleteMatch[1]) {
          return JSON.parse(lastCompleteMatch[1]);
        }
        
        // If that fails, try to find the last complete key-value pair
        const lastPairMatch = partialJson.match(/(\{[^{}]*"[^"]*"\s*:\s*"[^"]*"[^{}]*\})/);
        if (lastPairMatch && lastPairMatch[1]) {
          return JSON.parse(lastPairMatch[1]);
        }
        
        throw new Error('Unable to extract valid JSON from truncated response');
      }

      const jsonString = content.substring(startIndex, endIndex + 1);
      return JSON.parse(jsonString);
    } catch (error) {
      logger.error('Failed to extract JSON from LLM response', { 
        error, 
        contentLength: content.length,
        contentPreview: content.substring(0, 1000) 
      });
      throw new Error(`JSON extraction failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
  }

  /**
   * Estimate token count for text
   */
  private estimateTokenCount(text: string): number {
    // Rough estimation: 1 token ≈ 4 characters for English text
    return Math.ceil(text.length / 4);
  }

  /**
   * Select the best model for the task based on complexity and cost optimization
   */
  private selectModel(taskComplexity: 'simple' | 'complex' = 'complex', estimatedTokens: number = 0): string {
    const { enableCostOptimization, useFastModelForSimpleTasks, model, fastModel } = config.llm;
    
    // If cost optimization is enabled and task is simple, use fast model
    if (enableCostOptimization && useFastModelForSimpleTasks && taskComplexity === 'simple') {
      return fastModel;
    }
    
    // If estimated cost would exceed limit, use fast model
    if (enableCostOptimization && estimatedTokens > 0) {
      const estimatedCost = this.estimateCost(estimatedTokens, model);
      if (estimatedCost > config.llm.maxCostPerDocument) {
        return fastModel;
      }
    }
    
    // Default to primary model for complex tasks
    return model;
  }

  /**
   * Estimate cost for a given number of tokens and model
   */
  private estimateCost(tokens: number, model: string): number {
    // Rough cost estimation (in USD per 1M tokens)
    const costRates: Record<string, { input: number; output: number }> = {
      'claude-3-opus-20240229': { input: 15, output: 75 },
      'claude-3-5-sonnet-20241022': { input: 3, output: 15 },
      'claude-3-5-haiku-20241022': { input: 0.25, output: 1.25 },
      'gpt-4o': { input: 5, output: 15 },
      'gpt-4o-mini': { input: 0.15, output: 0.60 },
    };
    
    const rates = costRates[model] || costRates['claude-3-5-sonnet-20241022'];
    if (!rates) {
      return 0;
    }
    
    const inputCost = (tokens * 0.8 * rates.input) / 1000000; // Assume 80% input, 20% output
    const outputCost = (tokens * 0.2 * rates.output) / 1000000;
    
    return inputCost + outputCost;
  }

  /**
   * Determine task complexity based on document characteristics
   */
  private determineTaskComplexity(text: string, analysis: Record<string, any>): 'simple' | 'complex' {
    const textLength = text.length;
    const wordCount = analysis['wordCount'] || text.split(/\s+/).length;
    const hasFinancialData = analysis['hasFinancialData'] || false;
    const hasTechnicalData = analysis['hasTechnicalData'] || false;
    const complexity = analysis['complexity'] || 'medium';
    
    // Simple criteria
    if (textLength < 10000 && wordCount < 2000 && !hasFinancialData && !hasTechnicalData) {
      return 'simple';
    }
    
    // Complex criteria
    if (textLength > 50000 || wordCount > 10000 || hasFinancialData || hasTechnicalData || complexity === 'high') {
      return 'complex';
    }
    
    return 'complex'; // Default to complex for CIM documents
  }

  /**
   * Build refinement prompt for final summary improvement
   */
  private buildRefinementPrompt(text: string): string {
    return `
You are tasked with creating a final, comprehensive CIM review JSON object.

Below is a combined analysis from multiple document sections. Your job is to:
1. **Ensure completeness**: Make sure all fields in the JSON schema are properly filled out.
2. **Improve coherence**: Create smooth, logical content within the JSON structure.
3. **Remove redundancy**: Eliminate duplicate information.
4. **Maintain structure**: Follow the provided JSON schema exactly.

**Combined Analysis (as a JSON object):**
${text}

**JSON Schema:**
${JSON.stringify(cimReviewSchema.shape, null, 2)}

Please provide a refined, comprehensive CIM review as a single, valid JSON object.
`;
  }

  /**
   * Get system prompt for refinement mode
   */
  private getRefinementSystemPrompt(): string {
    return `You are an expert investment analyst. Your task is to refine and improve a combined JSON analysis into a final, professional CIM review.

Key responsibilities:
- Ensure the final output is a single, valid JSON object that conforms to the schema.
- Remove any duplicate or redundant information.
- Improve the flow and coherence of the content within the JSON structure.
- Enhance the clarity and professionalism of the analysis.
- Preserve all unique insights and important details.
`;
  }

  /**
   * Build overview prompt
   */
  private buildOverviewPrompt(text: string): string {
    return `
You are tasked with creating a comprehensive overview of the CIM document.

Your goal is to provide a high-level, strategic summary of the target company, its market position, and key factors driving its value.

CIM Document Text:
${text}

Your response MUST be a single, valid JSON object that follows the exact structure provided. Do not include any other text, explanations, or markdown formatting.

JSON Structure to Follow:
\`\`\`json
{
  "dealOverview": {
    "targetCompanyName": "Target Company Name",
    "industrySector": "Industry/Sector",
    "geography": "Geography (HQ & Key Operations)",
    "dealSource": "Deal Source",
    "transactionType": "Transaction Type",
    "dateCIMReceived": "Date CIM Received",
    "dateReviewed": "Date Reviewed",
    "reviewers": "Reviewer(s)",
    "cimPageCount": "CIM Page Count",
    "statedReasonForSale": "Stated Reason for Sale (if provided)"
  },
  "businessDescription": {
    "coreOperationsSummary": "Core Operations Summary (3-5 sentences)",
    "keyProductsServices": "Key Products/Services & Revenue Mix (Est. % if available)",
    "uniqueValueProposition": "Unique Value Proposition (UVP) / Why Customers Buy",
    "customerBaseOverview": {
      "keyCustomerSegments": "Key Customer Segments/Types",
      "customerConcentrationRisk": "Customer Concentration Risk (Top 5 and/or Top 10 Customers as % Revenue - if stated/inferable)",
      "typicalContractLength": "Typical Contract Length / Recurring Revenue % (if applicable)"
    },
    "keySupplierOverview": {
      "dependenceConcentrationRisk": "Dependence/Concentration Risk"
    }
  },
  "marketIndustryAnalysis": {
    "estimatedMarketSize": "Estimated Market Size (TAM/SAM - if provided)",
    "estimatedMarketGrowthRate": "Estimated Market Growth Rate (% CAGR - Historical & Projected)",
    "keyIndustryTrends": "Key Industry Trends & Drivers (Tailwinds/Headwinds)",
    "competitiveLandscape": {
      "keyCompetitors": "Key Competitors Identified",
      "targetMarketPosition": "Target's Stated Market Position/Rank",
      "basisOfCompetition": "Basis of Competition"
    },
    "barriersToEntry": "Barriers to Entry / Competitive Moat (Stated/Inferred)"
  },
  "financialSummary": {
    "financials": {
      "fy3": {
        "revenue": "Revenue amount for FY-3",
        "revenueGrowth": "N/A (baseline year)",
        "grossProfit": "Gross profit amount for FY-3",
        "grossMargin": "Gross margin % for FY-3",
        "ebitda": "EBITDA amount for FY-3",
        "ebitdaMargin": "EBITDA margin % for FY-3"
      },
      "fy2": {
        "revenue": "Revenue amount for FY-2",
        "revenueGrowth": "Revenue growth % for FY-2",
        "grossProfit": "Gross profit amount for FY-2",
        "grossMargin": "Gross margin % for FY-2",
        "ebitda": "EBITDA amount for FY-2",
        "ebitdaMargin": "EBITDA margin % for FY-2"
      },
      "fy1": {
        "revenue": "Revenue amount for FY-1",
        "revenueGrowth": "Revenue growth % for FY-1",
        "grossProfit": "Gross profit amount for FY-1",
        "grossMargin": "Gross margin % for FY-1",
        "ebitda": "EBITDA amount for FY-1",
        "ebitdaMargin": "EBITDA margin % for FY-1"
      },
      "ltm": {
        "revenue": "Revenue amount for LTM",
        "revenueGrowth": "Revenue growth % for LTM",
        "grossProfit": "Gross profit amount for LTM",
        "grossMargin": "Gross margin % for LTM",
        "ebitda": "EBITDA amount for LTM",
        "ebitdaMargin": "EBITDA margin % for LTM"
      }
    },
    "qualityOfEarnings": "Quality of earnings/adjustments impression",
    "revenueGrowthDrivers": "Revenue growth drivers (stated)",
    "marginStabilityAnalysis": "Margin stability/trend analysis",
    "capitalExpenditures": "Capital expenditures (LTM % of revenue)",
    "workingCapitalIntensity": "Working capital intensity impression",
    "freeCashFlowQuality": "Free cash flow quality impression"
  },
  "managementTeamOverview": {
    "keyLeaders": "Key Leaders Identified (CEO, CFO, COO, Head of Sales, etc.)",
    "managementQualityAssessment": "Initial Assessment of Quality/Experience (Based on Bios)",
    "postTransactionIntentions": "Management's Stated Post-Transaction Role/Intentions (if mentioned)",
    "organizationalStructure": "Organizational Structure Overview (Impression)"
  },
  "preliminaryInvestmentThesis": {
    "keyAttractions": "Key Attractions / Strengths (Why Invest?)",
    "potentialRisks": "Potential Risks / Concerns (Why Not Invest?)",
    "valueCreationLevers": "Initial Value Creation Levers (How PE Adds Value)",
    "alignmentWithFundStrategy": "Alignment with Fund Strategy (BPCP is focused on companies in 5+MM EBITDA range in consumer and industrial end markets. M&A, increased technology & data usage, supply chain and human capital optimization are key value-levers. Also a preference companies which are founder / family-owned and within driving distance of Cleveland and Charlotte.)"
  },
  "keyQuestionsNextSteps": {
    "criticalQuestions": "Critical Questions Arising from CIM Review",
    "missingInformation": "Key Missing Information / Areas for Diligence Focus",
    "preliminaryRecommendation": "Preliminary Recommendation",
    "rationaleForRecommendation": "Rationale for Recommendation (Brief)",
    "proposedNextSteps": "Proposed Next Steps"
  }
}
\`\`\`

IMPORTANT: Replace all placeholder text with actual information from the CIM document. If information is not available, use "Not specified in CIM". Ensure all financial metrics are properly formatted as strings.
`;
  }

  /**
   * Get system prompt for overview mode
   */
  private getOverviewSystemPrompt(): string {
    return `You are an expert investment analyst at BPCP (Blue Point Capital Partners) reviewing a Confidential Information Memorandum (CIM). Your task is to create a comprehensive, strategic overview of a CIM document and return a structured JSON object that follows the BPCP CIM Review Template format EXACTLY.

CRITICAL REQUIREMENTS:
1. **JSON OUTPUT ONLY**: Your entire response MUST be a single, valid JSON object. Do not include any text or explanation before or after the JSON object.
2. **BPCP TEMPLATE FORMAT**: The JSON object MUST follow the BPCP CIM Review Template structure exactly as specified.
3. **COMPLETE ALL FIELDS**: You MUST provide a value for every field. Use "Not specified in CIM" for any information that is not available in the document.
4. **NO PLACEHOLDERS**: Do not use placeholders like "..." or "TBD". Use "Not specified in CIM" instead.
5. **PROFESSIONAL ANALYSIS**: The content should be high-quality and suitable for BPCP's investment committee.
6. **BPCP FOCUS**: Focus on companies in 5+MM EBITDA range in consumer and industrial end markets, with emphasis on M&A, technology & data usage, supply chain and human capital optimization.
7. **BPCP PREFERENCES**: BPCP prefers companies which are founder/family-owned and within driving distance of Cleveland and Charlotte.
`;
  }

  /**
   * Build synthesis prompt
   */
  private buildSynthesisPrompt(text: string): string {
    return `
You are tasked with synthesizing the key findings and insights from the CIM document.

Your goal is to provide a cohesive, well-structured summary that highlights the most important aspects of the target company.

CIM Document Text:
${text}

Your response MUST be a single, valid JSON object that follows the exact structure provided. Do not include any other text, explanations, or markdown formatting.

JSON Structure to Follow:
\`\`\`json
{
  "dealOverview": {
    "targetCompanyName": "Target Company Name",
    "industrySector": "Industry/Sector",
    "geography": "Geography (HQ & Key Operations)",
    "dealSource": "Deal Source",
    "transactionType": "Transaction Type",
    "dateCIMReceived": "Date CIM Received",
    "dateReviewed": "Date Reviewed",
    "reviewers": "Reviewer(s)",
    "cimPageCount": "CIM Page Count",
    "statedReasonForSale": "Stated Reason for Sale (if provided)"
  },
  "businessDescription": {
    "coreOperationsSummary": "Core Operations Summary (3-5 sentences)",
    "keyProductsServices": "Key Products/Services & Revenue Mix (Est. % if available)",
    "uniqueValueProposition": "Unique Value Proposition (UVP) / Why Customers Buy",
    "customerBaseOverview": {
      "keyCustomerSegments": "Key Customer Segments/Types",
      "customerConcentrationRisk": "Customer Concentration Risk (Top 5 and/or Top 10 Customers as % Revenue - if stated/inferable)",
      "typicalContractLength": "Typical Contract Length / Recurring Revenue % (if applicable)"
    },
    "keySupplierOverview": {
      "dependenceConcentrationRisk": "Dependence/Concentration Risk"
    }
  },
  "marketIndustryAnalysis": {
    "estimatedMarketSize": "Estimated Market Size (TAM/SAM - if provided)",
    "estimatedMarketGrowthRate": "Estimated Market Growth Rate (% CAGR - Historical & Projected)",
    "keyIndustryTrends": "Key Industry Trends & Drivers (Tailwinds/Headwinds)",
    "competitiveLandscape": {
      "keyCompetitors": "Key Competitors Identified",
      "targetMarketPosition": "Target's Stated Market Position/Rank",
      "basisOfCompetition": "Basis of Competition"
    },
    "barriersToEntry": "Barriers to Entry / Competitive Moat (Stated/Inferred)"
  },
  "financialSummary": {
    "financials": {
      "fy3": {
        "revenue": "Revenue amount for FY-3",
        "revenueGrowth": "N/A (baseline year)",
        "grossProfit": "Gross profit amount for FY-3",
        "grossMargin": "Gross margin % for FY-3",
        "ebitda": "EBITDA amount for FY-3",
        "ebitdaMargin": "EBITDA margin % for FY-3"
      },
      "fy2": {
        "revenue": "Revenue amount for FY-2",
        "revenueGrowth": "Revenue growth % for FY-2",
        "grossProfit": "Gross profit amount for FY-2",
        "grossMargin": "Gross margin % for FY-2",
        "ebitda": "EBITDA amount for FY-2",
        "ebitdaMargin": "EBITDA margin % for FY-2"
      },
      "fy1": {
        "revenue": "Revenue amount for FY-1",
        "revenueGrowth": "Revenue growth % for FY-1",
        "grossProfit": "Gross profit amount for FY-1",
        "grossMargin": "Gross margin % for FY-1",
        "ebitda": "EBITDA amount for FY-1",
        "ebitdaMargin": "EBITDA margin % for FY-1"
      },
      "ltm": {
        "revenue": "Revenue amount for LTM",
        "revenueGrowth": "Revenue growth % for LTM",
        "grossProfit": "Gross profit amount for LTM",
        "grossMargin": "Gross margin % for LTM",
        "ebitda": "EBITDA amount for LTM",
        "ebitdaMargin": "EBITDA margin % for LTM"
      }
    },
    "qualityOfEarnings": "Quality of earnings/adjustments impression",
    "revenueGrowthDrivers": "Revenue growth drivers (stated)",
    "marginStabilityAnalysis": "Margin stability/trend analysis",
    "capitalExpenditures": "Capital expenditures (LTM % of revenue)",
    "workingCapitalIntensity": "Working capital intensity impression",
    "freeCashFlowQuality": "Free cash flow quality impression"
  },
  "managementTeamOverview": {
    "keyLeaders": "Key Leaders Identified (CEO, CFO, COO, Head of Sales, etc.)",
    "managementQualityAssessment": "Initial Assessment of Quality/Experience (Based on Bios)",
    "postTransactionIntentions": "Management's Stated Post-Transaction Role/Intentions (if mentioned)",
    "organizationalStructure": "Organizational Structure Overview (Impression)"
  },
  "preliminaryInvestmentThesis": {
    "keyAttractions": "Key Attractions / Strengths (Why Invest?)",
    "potentialRisks": "Potential Risks / Concerns (Why Not Invest?)",
    "valueCreationLevers": "Initial Value Creation Levers (How PE Adds Value)",
    "alignmentWithFundStrategy": "Alignment with Fund Strategy (BPCP is focused on companies in 5+MM EBITDA range in consumer and industrial end markets. M&A, increased technology & data usage, supply chain and human capital optimization are key value-levers. Also a preference companies which are founder / family-owned and within driving distance of Cleveland and Charlotte.)"
  },
  "keyQuestionsNextSteps": {
    "criticalQuestions": "Critical Questions Arising from CIM Review",
    "missingInformation": "Key Missing Information / Areas for Diligence Focus",
    "preliminaryRecommendation": "Preliminary Recommendation",
    "rationaleForRecommendation": "Rationale for Recommendation (Brief)",
    "proposedNextSteps": "Proposed Next Steps"
  }
}
\`\`\`

IMPORTANT: Replace all placeholder text with actual information from the CIM document. If information is not available, use "Not specified in CIM". Ensure all financial metrics are properly formatted as strings.
`;
  }

  /**
   * Get system prompt for synthesis mode
   */
  private getSynthesisSystemPrompt(): string {
    return `You are an expert investment analyst at BPCP (Blue Point Capital Partners) reviewing a Confidential Information Memorandum (CIM). Your task is to synthesize the key findings and insights from a CIM document and return a structured JSON object that follows the BPCP CIM Review Template format EXACTLY.

CRITICAL REQUIREMENTS:
1. **JSON OUTPUT ONLY**: Your entire response MUST be a single, valid JSON object. Do not include any text or explanation before or after the JSON object.
2. **BPCP TEMPLATE FORMAT**: The JSON object MUST follow the BPCP CIM Review Template structure exactly as specified.
3. **COMPLETE ALL FIELDS**: You MUST provide a value for every field. Use "Not specified in CIM" for any information that is not available in the document.
4. **NO PLACEHOLDERS**: Do not use placeholders like "..." or "TBD". Use "Not specified in CIM" instead.
5. **PROFESSIONAL ANALYSIS**: The content should be high-quality and suitable for BPCP's investment committee.
6. **BPCP FOCUS**: Focus on companies in 5+MM EBITDA range in consumer and industrial end markets, with emphasis on M&A, technology & data usage, supply chain and human capital optimization.
7. **BPCP PREFERENCES**: BPCP prefers companies which are founder/family-owned and within driving distance of Cleveland and Charlotte.
`;
  }

  /**
   * Build section prompt
   */
  private buildSectionPrompt(text: string, sectionType: string, analysis: Record<string, any>): string {
    const sectionName = sectionType.charAt(0).toUpperCase() + sectionType.slice(1);
    const overview = analysis['overview'];
    
    const sectionPrompt = `
You are tasked with analyzing the "${sectionName}" section of the CIM document.

Your goal is to provide a detailed, structured analysis of this section, building upon the document overview.

${overview ? `Document Overview Context:
${JSON.stringify(overview, null, 2)}

` : ''}CIM Document Text:
${text}

Your response MUST be a single, valid JSON object that follows the exact structure provided. Do not include any other text, explanations, or markdown formatting.

JSON Structure to Follow:
\`\`\`json
{
  "dealOverview": {
    "targetCompanyName": "Target Company Name",
    "industrySector": "Industry/Sector",
    "geography": "Geography (HQ & Key Operations)",
    "dealSource": "Deal Source",
    "transactionType": "Transaction Type",
    "dateCIMReceived": "Date CIM Received",
    "dateReviewed": "Date Reviewed",
    "reviewers": "Reviewer(s)",
    "cimPageCount": "CIM Page Count",
    "statedReasonForSale": "Stated Reason for Sale (if provided)"
  },
  "businessDescription": {
    "coreOperationsSummary": "Core Operations Summary (3-5 sentences)",
    "keyProductsServices": "Key Products/Services & Revenue Mix (Est. % if available)",
    "uniqueValueProposition": "Unique Value Proposition (UVP) / Why Customers Buy",
    "customerBaseOverview": {
      "keyCustomerSegments": "Key Customer Segments/Types",
      "customerConcentrationRisk": "Customer Concentration Risk (Top 5 and/or Top 10 Customers as % Revenue - if stated/inferable)",
      "typicalContractLength": "Typical Contract Length / Recurring Revenue % (if applicable)"
    },
    "keySupplierOverview": {
      "dependenceConcentrationRisk": "Dependence/Concentration Risk"
    }
  },
  "marketIndustryAnalysis": {
    "estimatedMarketSize": "Estimated Market Size (TAM/SAM - if provided)",
    "estimatedMarketGrowthRate": "Estimated Market Growth Rate (% CAGR - Historical & Projected)",
    "keyIndustryTrends": "Key Industry Trends & Drivers (Tailwinds/Headwinds)",
    "competitiveLandscape": {
      "keyCompetitors": "Key Competitors Identified",
      "targetMarketPosition": "Target's Stated Market Position/Rank",
      "basisOfCompetition": "Basis of Competition"
    },
    "barriersToEntry": "Barriers to Entry / Competitive Moat (Stated/Inferred)"
  },
  "financialSummary": {
    "financials": {
      "fy3": {
        "revenue": "Revenue amount for FY-3",
        "revenueGrowth": "N/A (baseline year)",
        "grossProfit": "Gross profit amount for FY-3",
        "grossMargin": "Gross margin % for FY-3",
        "ebitda": "EBITDA amount for FY-3",
        "ebitdaMargin": "EBITDA margin % for FY-3"
      },
      "fy2": {
        "revenue": "Revenue amount for FY-2",
        "revenueGrowth": "Revenue growth % for FY-2",
        "grossProfit": "Gross profit amount for FY-2",
        "grossMargin": "Gross margin % for FY-2",
        "ebitda": "EBITDA amount for FY-2",
        "ebitdaMargin": "EBITDA margin % for FY-2"
      },
      "fy1": {
        "revenue": "Revenue amount for FY-1",
        "revenueGrowth": "Revenue growth % for FY-1",
        "grossProfit": "Gross profit amount for FY-1",
        "grossMargin": "Gross margin % for FY-1",
        "ebitda": "EBITDA amount for FY-1",
        "ebitdaMargin": "EBITDA margin % for FY-1"
      },
      "ltm": {
        "revenue": "Revenue amount for LTM",
        "revenueGrowth": "Revenue growth % for LTM",
        "grossProfit": "Gross profit amount for LTM",
        "grossMargin": "Gross margin % for LTM",
        "ebitda": "EBITDA amount for LTM",
        "ebitdaMargin": "EBITDA margin % for LTM"
      }
    },
    "qualityOfEarnings": "Quality of earnings/adjustments impression",
    "revenueGrowthDrivers": "Revenue growth drivers (stated)",
    "marginStabilityAnalysis": "Margin stability/trend analysis",
    "capitalExpenditures": "Capital expenditures (LTM % of revenue)",
    "workingCapitalIntensity": "Working capital intensity impression",
    "freeCashFlowQuality": "Free cash flow quality impression"
  },
  "managementTeamOverview": {
    "keyLeaders": "Key Leaders Identified (CEO, CFO, COO, Head of Sales, etc.)",
    "managementQualityAssessment": "Initial Assessment of Quality/Experience (Based on Bios)",
    "postTransactionIntentions": "Management's Stated Post-Transaction Role/Intentions (if mentioned)",
    "organizationalStructure": "Organizational Structure Overview (Impression)"
  },
  "preliminaryInvestmentThesis": {
    "keyAttractions": "Key Attractions / Strengths (Why Invest?)",
    "potentialRisks": "Potential Risks / Concerns (Why Not Invest?)",
    "valueCreationLevers": "Initial Value Creation Levers (How PE Adds Value)",
    "alignmentWithFundStrategy": "Alignment with Fund Strategy (BPCP is focused on companies in 5+MM EBITDA range in consumer and industrial end markets. M&A, increased technology & data usage, supply chain and human capital optimization are key value-levers. Also a preference companies which are founder / family-owned and within driving distance of Cleveland and Charlotte.)"
  },
  "keyQuestionsNextSteps": {
    "criticalQuestions": "Critical Questions Arising from CIM Review",
    "missingInformation": "Key Missing Information / Areas for Diligence Focus",
    "preliminaryRecommendation": "Preliminary Recommendation",
    "rationaleForRecommendation": "Rationale for Recommendation (Brief)",
    "proposedNextSteps": "Proposed Next Steps"
  }
}
\`\`\`

IMPORTANT: Replace all placeholder text with actual information from the CIM document. If information is not available, use "Not specified in CIM". Ensure all financial metrics are properly formatted as strings.
`;
    return sectionPrompt;
  }

  /**
   * Get system prompt for section mode
   */
  private getSectionSystemPrompt(sectionType: string): string {
    const sectionName = sectionType.charAt(0).toUpperCase() + sectionType.slice(1);
    return `You are an expert investment analyst at BPCP (Blue Point Capital Partners) reviewing a Confidential Information Memorandum (CIM). Your task is to analyze the "${sectionName}" section of the CIM document and return a comprehensive, structured JSON object that follows the BPCP CIM Review Template format EXACTLY.

CRITICAL REQUIREMENTS:
1. **JSON OUTPUT ONLY**: Your entire response MUST be a single, valid JSON object. Do not include any text or explanation before or after the JSON object.
2. **BPCP TEMPLATE FORMAT**: The JSON object MUST follow the BPCP CIM Review Template structure exactly as specified.
3. **SECTION FOCUS**: Focus specifically on the ${sectionName.toLowerCase()} aspects of the company.
4. **COMPLETE ALL FIELDS**: You MUST provide a value for every field. Use "Not specified in CIM" for any information that is not available in the document.
5. **NO PLACEHOLDERS**: Do not use placeholders like "..." or "TBD". Use "Not specified in CIM" instead.
6. **PROFESSIONAL ANALYSIS**: The content should be high-quality and suitable for BPCP's investment committee.
7. **BPCP FOCUS**: Focus on companies in 5+MM EBITDA range in consumer and industrial end markets, with emphasis on M&A, technology & data usage, supply chain and human capital optimization.
8. **BPCP PREFERENCES**: BPCP prefers companies which are founder/family-owned and within driving distance of Cleveland and Charlotte.
`;
  }
}

export const llmService = new LLMService();
export default llmService; 