import { ServerResult } from '../types.js';
import { usageTracker } from '../utils/usageTracker.js';
import { capture } from '../utils/capture.js';
import * as fs from 'fs/promises';
import * as path from 'path';
import { fileURLToPath } from 'url';

// Get the directory path for ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

interface Prompt {
  id: string;
  title: string;
  description: string;
  prompt: string;
  categories: string[];
  secondaryTag?: string;
  votes: number;
  gaClicks: number;
  icon: string;
  author: string;
  verified: boolean;
}

export interface PromptsData {
  version: string;
  description: string;
  prompts: Prompt[];
}

interface GetPromptsParams {
  action: 'get_prompt';
  promptId: string;
  anonymous_user_use_case?: string;
}

let cachedPromptsData: PromptsData | null = null;

/**
 * Clear cached prompts data (for development/testing)
 */
function clearCache(): void {
  cachedPromptsData = null;
}

/**
 * Load prompts data from JSON file with caching
 */
export async function loadPromptsData(): Promise<PromptsData> {
   if (cachedPromptsData) {
     return cachedPromptsData;
   }

  try {
    const dataPath = path.join(__dirname, '..', 'data', 'onboarding-prompts.json');
    const fileContent = await fs.readFile(dataPath, 'utf-8');
    cachedPromptsData = JSON.parse(fileContent);
    
    if (!cachedPromptsData) {
      throw new Error('Failed to parse prompts data');
    }
    
    return cachedPromptsData;
  } catch (error) {
    throw new Error(`Failed to load prompts data: ${error instanceof Error ? error.message : String(error)}`);
  }
}

/**
 * Get prompts - SIMPLIFIED VERSION (only get_prompt action)
 */
export async function getPrompts(params: any): Promise<ServerResult> {
  try {
    // Validate and cast parameters
    const { action, promptId, anonymous_user_use_case } = params as GetPromptsParams;
    
    if (!action) {
      return {
        content: [{
          type: "text",
          text: "❌ Error: 'action' parameter is required. Use 'get_prompt'"
        }],
        isError: true
      };
    }

    // Only support get_prompt action now
    if (action === 'get_prompt') {
      if (!promptId) {
        return {
          content: [{
            type: "text",
            text: "❌ Error: promptId is required when action is 'get_prompt'"
          }],
          isError: true
        };
      }
      return await getPrompt(promptId, anonymous_user_use_case);
    }
    
    // Legacy actions return deprecation notice
    return {
      content: [{
        type: "text",
        text: "❌ Error: Only 'get_prompt' action is supported. Use promptId to get a specific prompt."
      }],
      isError: true
    };
  } catch (error) {
    return {
      content: [{
        type: "text",
        text: `❌ Error: ${error instanceof Error ? error.message : String(error)}`
      }],
      isError: true
    };
  }
}

/**
 * List all available categories
 */
async function listCategories(): Promise<ServerResult> {
  const data = await loadPromptsData();
  
  // Extract unique categories and count prompts in each
  const categoryMap = new Map<string, number>();
  data.prompts.forEach(prompt => {
    prompt.categories.forEach(category => {
      categoryMap.set(category, (categoryMap.get(category) || 0) + 1);
    });
  });

  const categories = Array.from(categoryMap.entries()).map(([name, count]) => ({
    name,
    count,
    description: getCategoryDescription(name)
  }));

  const response = formatCategoriesResponse(categories, data.prompts.length);
  
  return {
    content: [{
      type: "text",
      text: response
    }]
  };
}

/**
 * List prompts, optionally filtered by category
 */
async function listPrompts(category?: string): Promise<ServerResult> {
  const data = await loadPromptsData();
  
  let filteredPrompts = data.prompts;
  
  // Filter by category if specified
  if (category) {
    filteredPrompts = data.prompts.filter(prompt => 
      prompt.categories.includes(category)
    );
    
    if (filteredPrompts.length === 0) {
      return {
        content: [{
          type: "text",
          text: `❌ No prompts found in category "${category}". Use action='list_categories' to see available categories.`
        }],
        isError: true
      };
    }
  }

  const response = formatPromptsListResponse(filteredPrompts, category);
  
  return {
    content: [{
      type: "text",
      text: response
    }]
  };
}

/**
 * Get a specific prompt by ID and inject it into the chat
 */
async function getPrompt(promptId: string, anonymousUseCase?: string): Promise<ServerResult> {
  const data = await loadPromptsData();
  
  const prompt = data.prompts.find(p => p.id === promptId);
  
  if (!prompt) {
    return {
      content: [{
        type: "text",
        text: `❌ Prompt with ID '${promptId}' not found. Use action='list_prompts' to see available prompts.`
      }],
      isError: true
    };
  }

  // Mark prompt as used in user's onboarding state (for analytics)
  await usageTracker.markPromptUsed(promptId, prompt.categories[0] || 'uncategorized');
  
  const response = formatPromptResponse(prompt);
  
  return {
    content: [{
      type: "text",
      text: response
    }]
  };
}

/**
 * Get category description (can be expanded later)
 */
function getCategoryDescription(category: string): string {
  const descriptions: Record<string, string> = {
    'onboarding': 'Curated prompts perfect for first-time Desktop Commander users',
    'Analyze data': 'Data analysis, visualization, and insights generation',
    'Build features and products': 'Full-stack development and application building',
    'Explore codebase': 'Code analysis, documentation, and understanding',
    'Organize files': 'File management, cleanup, and organization',
    'Deploy': 'Infrastructure setup, deployment, and DevOps tasks',
    'Optimize code': 'Code optimization, refactoring, and performance',
    'Write documentation': 'Technical writing, API docs, and guides',
    'Optimize workflow': 'Process improvements and productivity enhancements',
    'Automate tasks': 'Workflow automation and scripting',
    'Design systems': 'Architecture planning and system design'
  };
  
  return descriptions[category] || 'Desktop Commander prompts and workflows';
}

/**
 * Format categories list response
 */
function formatCategoriesResponse(categories: Array<{name: string, count: number, description: string}>, totalPrompts: number): string {
  const sortedCategories = categories.sort((a, b) => b.count - a.count);
  
  // AI INSTRUCTION: When listing prompts, do not show prompt IDs to users - they are for your reference only
  let response = `📚 **Desktop Commander Prompt Categories** (${categories.length} categories, ${totalPrompts} prompts)\n\n`;
  
  sortedCategories.forEach(cat => {
    response += `• **${cat.name}** (${cat.count} prompts) - ${cat.description}\n`;
  });
  
  response += `\n**Usage:**\n`;
  response += `• \`get_prompts(action='list_prompts', category='onboarding')\` - See prompts in category\n`;
  response += `• \`get_prompts(action='list_prompts')\` - See all available prompts\n`;
  response += `• \`get_prompts(action='get_prompt', promptId='PROMPT_ID')\` - Get a specific prompt`;
  
  return response;
}

/**
 * Format prompts list response using secondary tags for clean organization
 */
function formatPromptsListResponse(prompts: Prompt[], category?: string): string {
  const categoryText = category ? ` in "${category}"` : '';
  
  let response = `Desktop Commander Examples${categoryText}\n\n`;
  
  // Group by secondary tag
  const groupedPrompts = new Map<string, Prompt[]>();
  prompts.forEach(prompt => {
    const tag = prompt.secondaryTag || 'Other';
    if (!groupedPrompts.has(tag)) {
      groupedPrompts.set(tag, []);
    }
    groupedPrompts.get(tag)!.push(prompt);
  });
  
  let promptNumber = 1;
  
  // Display groups in preferred order
  const preferredOrder = ['Quick Start', 'Code Analysis', 'Build & Deploy', 'Other'];
  
  preferredOrder.forEach(tag => {
    if (groupedPrompts.has(tag)) {
      const tagPrompts = groupedPrompts.get(tag)!;
      // Add emoji for each section
      const emoji = tag === 'Quick Start' ? '🚀' : tag === 'Code Analysis' ? '💻' : tag === 'Build & Deploy' ? '🔨' : '📋';
      response += `**${emoji} ${tag}**\n`;
      tagPrompts.forEach(prompt => {
        response += `• ${promptNumber}. ${prompt.title}\n`;
        promptNumber++;
      });
      response += `\n`;
    }
  });
  
  response += `Say "Try #3" or "Let's do #1" to start any example.\n\n`;
  response += `<INSTRUCTION>Output options for user exactly as provided without missing numbers. 
Its important so user can choose an options by entering number only. Also do not forget new lines between numbers for easy reading</INSTRUCTION>\n\n`;

  // AI reference mapping (do not show to user):
  response += `<!-- AI_PROMPT_MAP: `;
  let mapNumber = 1;
  preferredOrder.forEach(tag => {
    if (groupedPrompts.has(tag)) {
      groupedPrompts.get(tag)!.forEach(prompt => {
        response += `${mapNumber}=${prompt.id}${mapNumber < prompts.length ? ',' : ''}`;
        mapNumber++;
      });
    }
  });
  response += ` -->`;
  
  return response;
}

/**
 * Format individual prompt response with the actual prompt content
 */
function formatPromptResponse(prompt: Prompt): string {
  const verifiedBadge = prompt.verified ? ' ✅' : '';
  const categoryText = prompt.categories.join(', ');
  
  let response = `# 🎯 ${prompt.title}${verifiedBadge}\n\n`;
  response += `**Category:** ${categoryText} • **Author:** ${prompt.author}\n\n`;
  response += `## Description\n${prompt.description}\n\n`;
  
  if (prompt.votes > 0) {
    response += `*📊 This prompt has been used successfully by ${prompt.votes}+ users*\n\n`;
  }
  
  response += `## Ready to Use This Prompt\nThe prompt below is ready to use. I'll start executing it right away:\n\n`;
  response += `---\n\n${prompt.prompt}`;
  
  // AI metadata (not shown to user): Executed prompt ID = ${prompt.id}
  
  return response;
}
