/* eslint-disable @typescript-eslint/no-unused-vars */
import type { QueryIntent, ExtractedEntities } from './types.js';

// ============================================================================
// Natural Language Query Parser
// ============================================================================

export interface ParsedQuery {
  rawQuery: string;
  intent: QueryIntent;
  entities: ExtractedEntities;
  constraints: string[];
}

// Time-related regex patterns
const TIME_PATTERNS = {
  yesterday: /yesterday/i,
  today: /today/i,
  lastWeek: /last\s+week/i,
  lastMonth: /last\s+month/i,
  thisWeek: /this\s+week/i,
  thisMonth: /this\s+month/i,
  sinceVersion: /since\s+(?:version|v)?\s*([\d.]+)/i,
  specificDate: /(?:on|after|before|since)\s+(\d{4}-\d{2}-\d{2}|\d{2}\/\d{2}\/\d{4})/i,
  daysAgo: /(\d+)\s+days?\s+ago/i,
  hoursAgo: /(\d+)\s+hours?\s+ago/i,
};

// Platform patterns
const PLATFORM_PATTERNS = {
  ios: /\bios\b/i,
  android: /\bandroid\b/i,
  web: /\bweb\b/i,
  desktop: /\b(?:desktop|mac|windows|linux)\b/i,
};

// Intent keywords
const INTENT_KEYWORDS: Record<QueryIntent, string[]> = {
  root_cause: ['why', 'what caused', 'reason for', 'explain', 'root cause', 'how come'],
  pattern_search: ['show me', 'find', 'search for', 'similar', 'like', 'pattern', 'trend'],
  comparison: [
    'compare',
    'difference',
    'versus',
    'vs',
    'more than',
    'less than',
    'increase',
    'decrease',
  ],
  trend: ['trend', 'over time', 'graph', 'chart', 'history', 'pattern over'],
  impact: ['how many', 'affected', 'users impacted', 'scope', 'magnitude', 'count'],
};

// Error type patterns
const ERROR_TYPE_PATTERNS = [
  /(?:NullPointer|TypeError|ReferenceError|Cannot read property)/i,
  /(?:crash|exception|error|failure|timeout|deadlock)/i,
  /(?:memory|leak|OOM|out of memory)/i,
  /(?:network|connection|fetch|axios|http|api)/i,
  /(?:authentication|auth|login|permission|unauthorized)/i,
  /(?:database|query|sql|mongo|cosmos)/i,
  /(?:ui|render|component|react|vue|angular)/i,
];

/**
 * Parses a natural language query into structured intent and entities
 */
export function parseQuery(rawQuery: string): ParsedQuery {
  const lowerQuery = rawQuery.toLowerCase();

  // Classify intent
  const intent = classifyIntent(lowerQuery);

  // Extract entities
  const entities = extractEntities(lowerQuery, rawQuery);

  // Extract constraints
  const constraints = extractConstraints(lowerQuery);

  return {
    rawQuery,
    intent,
    entities,
    constraints,
  };
}

/**
 * Classifies the query intent based on keywords
 */
function classifyIntent(query: string): QueryIntent {
  const scores: Record<QueryIntent, number> = {
    root_cause: 0,
    pattern_search: 0,
    comparison: 0,
    trend: 0,
    impact: 0,
  };

  // Score each intent based on keyword matches
  for (const [intent, keywords] of Object.entries(INTENT_KEYWORDS)) {
    for (const keyword of keywords) {
      if (query.includes(keyword)) {
        scores[intent as QueryIntent] += 1;
      }
    }
  }

  // Special cases
  if (query.includes('why did') || query.includes('why does')) {
    scores.root_cause += 2;
  }

  if (query.match(/\b(how many|count|number of)\b/)) {
    scores.impact += 2;
  }

  // Return highest scoring intent
  const sorted = Object.entries(scores).sort((a, b) => b[1] - a[1]);
  return (sorted[0][1] > 0 ? sorted[0][0] : 'root_cause') as QueryIntent;
}

/**
 * Extracts entities from the query
 */
function extractEntities(lowerQuery: string, rawQuery: string): ExtractedEntities {
  const entities: ExtractedEntities = {};

  // Extract time range
  entities.timeRange = extractTimeRange(lowerQuery, rawQuery);

  // Extract platforms
  entities.platforms = extractPlatforms(lowerQuery);

  // Extract error types
  entities.errorTypes = extractErrorTypes(lowerQuery);

  // Extract products (look for product mentions)
  entities.products = extractProducts(lowerQuery);

  return entities;
}

/**
 * Extracts time range from query
 */
function extractTimeRange(lowerQuery: string, rawQuery: string): ExtractedEntities['timeRange'] {
  const now = new Date();
  let start: Date | null = null;
  let end: Date = now;

  // Check various time patterns
  if (TIME_PATTERNS.yesterday.test(lowerQuery)) {
    start = new Date(now.getTime() - 24 * 60 * 60 * 1000);
    end = new Date(now.getTime());
    // Set to start/end of day
    start.setHours(0, 0, 0, 0);
    end.setHours(23, 59, 59, 999);
  } else if (TIME_PATTERNS.today.test(lowerQuery)) {
    start = new Date(now);
    start.setHours(0, 0, 0, 0);
  } else if (TIME_PATTERNS.lastWeek.test(lowerQuery)) {
    start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
    end = now;
  } else if (TIME_PATTERNS.lastMonth.test(lowerQuery)) {
    start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
    end = now;
  } else if (TIME_PATTERNS.daysAgo.test(lowerQuery)) {
    const match = lowerQuery.match(TIME_PATTERNS.daysAgo);
    if (match) {
      const days = parseInt(match[1], 10);
      start = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
    }
  } else if (TIME_PATTERNS.hoursAgo.test(lowerQuery)) {
    const match = lowerQuery.match(TIME_PATTERNS.hoursAgo);
    if (match) {
      const hours = parseInt(match[1], 10);
      start = new Date(now.getTime() - hours * 60 * 60 * 1000);
    }
  }

  // Default to last 7 days if no time specified
  if (!start) {
    start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
  }

  return {
    start: start.toISOString(),
    end: end.toISOString(),
  };
}

/**
 * Extracts platforms from query
 */
function extractPlatforms(lowerQuery: string): string[] {
  const platforms: string[] = [];

  if (PLATFORM_PATTERNS.ios.test(lowerQuery)) platforms.push('ios');
  if (PLATFORM_PATTERNS.android.test(lowerQuery)) platforms.push('android');
  if (PLATFORM_PATTERNS.web.test(lowerQuery)) platforms.push('web');
  if (PLATFORM_PATTERNS.desktop.test(lowerQuery)) platforms.push('desktop');

  return platforms;
}

/**
 * Extracts error types from query
 */
function extractErrorTypes(lowerQuery: string): string[] {
  const errorTypes: string[] = [];

  for (const pattern of ERROR_TYPE_PATTERNS) {
    if (pattern.test(lowerQuery)) {
      // Extract the matched text
      const match = lowerQuery.match(pattern);
      if (match && !errorTypes.includes(match[0])) {
        errorTypes.push(match[0]);
      }
    }
  }

  return errorTypes;
}

/**
 * Extracts product mentions from query
 */
function extractProducts(lowerQuery: string): string[] {
  const products: string[] = [];

  // Known product IDs
  const knownProducts = ['lysnrai', 'mindlyst', 'chronomind', 'jarvisjr', 'nomgap', 'peakpulse'];

  for (const product of knownProducts) {
    if (lowerQuery.includes(product)) {
      products.push(product);
    }
  }

  return products;
}

/**
 * Extracts constraints from query
 */
function extractConstraints(lowerQuery: string): string[] {
  const constraints: string[] = [];

  // Exclusion constraints
  const excludeMatch = lowerQuery.match(/excluding?\s+(\w+)/i);
  if (excludeMatch) {
    constraints.push(`exclude:${excludeMatch[1]}`);
  }

  // Only/beta constraints
  if (lowerQuery.includes('only beta') || lowerQuery.includes('beta only')) {
    constraints.push('userSegment:beta');
  }

  if (lowerQuery.includes('only production') || lowerQuery.includes('production only')) {
    constraints.push('environment:production');
  }

  return constraints;
}

// ============================================================================
// Query Patterns
// ============================================================================

export interface QueryPattern {
  name: string;
  description: string;
  examples: string[];
  intent: QueryIntent;
  requiredEntities: (keyof ExtractedEntities)[];
  optionalEntities: (keyof ExtractedEntities)[];
}

export const QUERY_PATTERNS: QueryPattern[] = [
  {
    name: 'root_cause_investigation',
    description: 'Investigate why an error occurred',
    examples: [
      'Why did the iOS keyboard crash yesterday?',
      'What caused the authentication failures?',
      'Explain the memory leak in the dashboard',
    ],
    intent: 'root_cause',
    requiredEntities: [],
    optionalEntities: ['errorTypes', 'platforms', 'timeRange', 'products'],
  },
  {
    name: 'similar_errors_search',
    description: 'Find errors similar to a specific one',
    examples: [
      'Show me similar database errors',
      'Find crashes like the login timeout',
      'Search for API failures in the last week',
    ],
    intent: 'pattern_search',
    requiredEntities: [],
    optionalEntities: ['errorTypes', 'timeRange', 'platforms'],
  },
  {
    name: 'trend_analysis',
    description: 'Analyze error trends over time',
    examples: [
      'Did error rate increase after the release?',
      'Show me the trend for timeout errors',
      'Compare this week to last week',
    ],
    intent: 'trend',
    requiredEntities: ['timeRange'],
    optionalEntities: ['errorTypes'],
  },
  {
    name: 'impact_assessment',
    description: 'Assess user impact of errors',
    examples: [
      'How many users were affected by the crash?',
      'What is the scope of the authentication bug?',
      'Count errors by platform',
    ],
    intent: 'impact',
    requiredEntities: [],
    optionalEntities: ['errorTypes', 'platforms', 'timeRange'],
  },
  {
    name: 'cluster_comparison',
    description: 'Compare two error clusters',
    examples: [
      'Compare cluster A to cluster B',
      'Is this the same issue as last month?',
      'What is the difference between these errors?',
    ],
    intent: 'comparison',
    requiredEntities: [],
    optionalEntities: ['clusterIds'],
  },
];

/**
 * Matches a parsed query to known patterns
 */
export function matchQueryPattern(parsedQuery: ParsedQuery): QueryPattern | null {
  for (const pattern of QUERY_PATTERNS) {
    if (pattern.intent === parsedQuery.intent) {
      // Check if required entities are present
      const hasRequired = pattern.requiredEntities.every(
        entity => parsedQuery.entities[entity] !== undefined
      );

      if (hasRequired) {
        return pattern;
      }
    }
  }

  return null;
}

// ============================================================================
// Query Suggestions
// ============================================================================

interface QuerySuggestion {
  query: string;
  description: string;
  pattern: string;
}

/**
 * Generates suggested queries based on recent errors
 */
export function generateQuerySuggestions(
  recentErrorTypes: string[],
  platforms: string[]
): QuerySuggestion[] {
  const suggestions: QuerySuggestion[] = [];

  // Root cause suggestions
  for (const errorType of recentErrorTypes.slice(0, 3)) {
    suggestions.push({
      query: `Why are there ${errorType} errors?`,
      description: 'Investigate root cause',
      pattern: 'root_cause_investigation',
    });
  }

  // Impact suggestions
  suggestions.push({
    query: 'How many users were affected by recent errors?',
    description: 'Assess user impact',
    pattern: 'impact_assessment',
  });

  // Trend suggestions
  suggestions.push({
    query: 'Show error trends over the last 7 days',
    description: 'View error trends',
    pattern: 'trend_analysis',
  });

  // Platform-specific
  for (const platform of platforms.slice(0, 2)) {
    suggestions.push({
      query: `Show ${platform} errors from today`,
      description: `View ${platform} specific errors`,
      pattern: 'similar_errors_search',
    });
  }

  return suggestions.slice(0, 6);
}

// ============================================================================
// Query Validation
// ============================================================================

interface ValidationResult {
  valid: boolean;
  errors: string[];
  warnings: string[];
}

/**
 * Validates a parsed query
 */
export function validateQuery(parsedQuery: ParsedQuery): ValidationResult {
  const errors: string[] = [];
  const warnings: string[] = [];

  // Check if query is too vague
  const hasSpecificEntity =
    parsedQuery.entities.errorTypes?.length ||
    parsedQuery.entities.platforms?.length ||
    parsedQuery.entities.products?.length;

  if (!hasSpecificEntity) {
    warnings.push('Query is broad. Consider specifying error type, platform, or product.');
  }

  // Check time range
  if (parsedQuery.entities.timeRange) {
    const start = new Date(parsedQuery.entities.timeRange.start);
    const end = new Date(parsedQuery.entities.timeRange.end);
    const daysDiff = (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24);

    if (daysDiff > 90) {
      warnings.push('Time range exceeds 90 days. Results may be slow.');
    }
  }

  return {
    valid: errors.length === 0,
    errors,
    warnings,
  };
}
