import { DatabaseAdapter } from '../database/database-adapter';
import { TemplateRepository, StoredTemplate } from './template-repository';
import { logger } from '../utils/logger';

export interface TemplateInfo {
  id: number;
  name: string;
  description: string;
  author: {
    name: string;
    username: string;
    verified: boolean;
  };
  nodes: string[];
  views: number;
  created: string;
  url: string;
}

export interface TemplateWithWorkflow extends TemplateInfo {
  workflow: any;
}

export class TemplateService {
  private repository: TemplateRepository;
  
  constructor(db: DatabaseAdapter) {
    this.repository = new TemplateRepository(db);
  }
  
  /**
   * List templates that use specific node types
   */
  async listNodeTemplates(nodeTypes: string[], limit: number = 10): Promise<TemplateInfo[]> {
    const templates = this.repository.getTemplatesByNodes(nodeTypes, limit);
    return templates.map(this.formatTemplateInfo);
  }
  
  /**
   * Get a specific template with full workflow
   */
  async getTemplate(templateId: number): Promise<TemplateWithWorkflow | null> {
    const template = this.repository.getTemplate(templateId);
    if (!template) {
      return null;
    }
    
    return {
      ...this.formatTemplateInfo(template),
      workflow: JSON.parse(template.workflow_json)
    };
  }
  
  /**
   * Search templates by query
   */
  async searchTemplates(query: string, limit: number = 20): Promise<TemplateInfo[]> {
    const templates = this.repository.searchTemplates(query, limit);
    return templates.map(this.formatTemplateInfo);
  }
  
  /**
   * Get templates for a specific task
   */
  async getTemplatesForTask(task: string): Promise<TemplateInfo[]> {
    const templates = this.repository.getTemplatesForTask(task);
    return templates.map(this.formatTemplateInfo);
  }
  
  /**
   * List available tasks
   */
  listAvailableTasks(): string[] {
    return [
      'ai_automation',
      'data_sync',
      'webhook_processing',
      'email_automation',
      'slack_integration',
      'data_transformation',
      'file_processing',
      'scheduling',
      'api_integration',
      'database_operations'
    ];
  }
  
  /**
   * Get template statistics
   */
  async getTemplateStats(): Promise<Record<string, any>> {
    return this.repository.getTemplateStats();
  }
  
  /**
   * Fetch and update templates from n8n.io
   */
  async fetchAndUpdateTemplates(
    progressCallback?: (message: string, current: number, total: number) => void
  ): Promise<void> {
    try {
      // Dynamically import fetcher only when needed (requires axios)
      const { TemplateFetcher } = await import('./template-fetcher');
      const fetcher = new TemplateFetcher();
      
      // Clear existing templates
      this.repository.clearTemplates();
      
      // Fetch template list
      logger.info('Fetching template list from n8n.io');
      const templates = await fetcher.fetchTemplates((current, total) => {
        progressCallback?.('Fetching template list', current, total);
      });
      
      logger.info(`Found ${templates.length} templates from last year`);
      
      // Fetch details for each template
      logger.info('Fetching template details');
      const details = await fetcher.fetchAllTemplateDetails(templates, (current, total) => {
        progressCallback?.('Fetching template details', current, total);
      });
      
      // Save to database
      logger.info('Saving templates to database');
      let saved = 0;
      for (const template of templates) {
        const detail = details.get(template.id);
        if (detail) {
          this.repository.saveTemplate(template, detail);
          saved++;
        }
      }
      
      logger.info(`Successfully saved ${saved} templates to database`);
      
      // Rebuild FTS5 index after bulk import
      logger.info('Rebuilding FTS5 index for templates');
      this.repository.rebuildTemplateFTS();
      
      progressCallback?.('Complete', saved, saved);
    } catch (error) {
      logger.error('Error fetching templates:', error);
      throw error;
    }
  }
  
  /**
   * Format stored template for API response
   */
  private formatTemplateInfo(template: StoredTemplate): TemplateInfo {
    return {
      id: template.id,
      name: template.name,
      description: template.description,
      author: {
        name: template.author_name,
        username: template.author_username,
        verified: template.author_verified === 1
      },
      nodes: JSON.parse(template.nodes_used),
      views: template.views,
      created: template.created_at,
      url: template.url
    };
  }
}