const database = require('../config/database');
const { v4: uuidv4 } = require('uuid');

class TechStackRecommendation {
  constructor(data = {}) {
    this.id = data.id;
    this.template_id = data.template_id;
    this.template_type = data.template_type;
    this.frontend = data.frontend;
    this.backend = data.backend;
    this.mobile = data.mobile;
    this.testing = data.testing;
    this.ai_ml = data.ai_ml;
    this.devops = data.devops;
    this.cloud = data.cloud;
    this.tools = data.tools;
    this.analysis_context = data.analysis_context;
    this.confidence_scores = data.confidence_scores;
    this.reasoning = data.reasoning;
    this.ai_model = data.ai_model;
    this.analysis_version = data.analysis_version;
    this.status = data.status;
    this.error_message = data.error_message;
    this.processing_time_ms = data.processing_time_ms;
    this.created_at = data.created_at;
    this.updated_at = data.updated_at;
    this.last_analyzed_at = data.last_analyzed_at;
  }

  // Get recommendation by template ID
  static async getByTemplateId(templateId, templateType = null) {
    let query = 'SELECT * FROM tech_stack_recommendations WHERE template_id = $1';
    const params = [templateId];
    
    if (templateType) {
      query += ' AND template_type = $2';
      params.push(templateType);
    }
    
    query += ' ORDER BY last_analyzed_at DESC LIMIT 1';
    
    const result = await database.query(query, params);
    return result.rows.length > 0 ? new TechStackRecommendation(result.rows[0]) : null;
  }

  // Get recommendation by ID
  static async getById(id) {
    const result = await database.query('SELECT * FROM tech_stack_recommendations WHERE id = $1', [id]);
    return result.rows.length > 0 ? new TechStackRecommendation(result.rows[0]) : null;
  }

  // Create new recommendation
  static async create(data) {
    const id = uuidv4();
    const query = `
      INSERT INTO tech_stack_recommendations (
        id, template_id, template_type, frontend, backend, mobile, testing,
        ai_ml, devops, cloud, tools, analysis_context, confidence_scores,
        reasoning, ai_model, analysis_version, status, error_message,
        processing_time_ms, last_analyzed_at
      ) VALUES (
        $1, $2, $3, $4::jsonb, $5::jsonb, $6::jsonb, $7::jsonb,
        $8::jsonb, $9::jsonb, $10::jsonb, $11::jsonb, $12::jsonb, $13::jsonb,
        $14::jsonb, $15, $16, $17, $18, $19, $20
      )
      RETURNING *
    `;
    
    const values = [
      id,
      data.template_id,
      data.template_type,
      data.frontend ? JSON.stringify(data.frontend) : null,
      data.backend ? JSON.stringify(data.backend) : null,
      data.mobile ? JSON.stringify(data.mobile) : null,
      data.testing ? JSON.stringify(data.testing) : null,
      data.ai_ml ? JSON.stringify(data.ai_ml) : null,
      data.devops ? JSON.stringify(data.devops) : null,
      data.cloud ? JSON.stringify(data.cloud) : null,
      data.tools ? JSON.stringify(data.tools) : null,
      data.analysis_context ? JSON.stringify(data.analysis_context) : null,
      data.confidence_scores ? JSON.stringify(data.confidence_scores) : null,
      data.reasoning ? JSON.stringify(data.reasoning) : null,
      data.ai_model || 'claude-3-5-sonnet-20241022',
      data.analysis_version || '1.0',
      data.status || 'completed',
      data.error_message || null,
      data.processing_time_ms || null,
      data.last_analyzed_at || new Date()
    ];
    
    const result = await database.query(query, values);
    return new TechStackRecommendation(result.rows[0]);
  }

  // Update recommendation
  static async update(id, updates) {
    const fields = [];
    const values = [];
    let idx = 1;
    
    const allowed = [
      'frontend', 'backend', 'mobile', 'testing', 'ai_ml', 'devops', 'cloud', 'tools',
      'analysis_context', 'confidence_scores', 'reasoning', 'ai_model', 'analysis_version',
      'status', 'error_message', 'processing_time_ms', 'last_analyzed_at'
    ];
    
    for (const key of allowed) {
      if (updates[key] !== undefined) {
        if (['frontend', 'backend', 'mobile', 'testing', 'ai_ml', 'devops', 'cloud', 'tools', 
             'analysis_context', 'confidence_scores', 'reasoning'].includes(key)) {
          fields.push(`${key} = $${idx++}::jsonb`);
          values.push(updates[key] ? JSON.stringify(updates[key]) : null);
        } else {
          fields.push(`${key} = $${idx++}`);
          values.push(updates[key]);
        }
      }
    }
    
    if (fields.length === 0) {
      return await TechStackRecommendation.getById(id);
    }
    
    const query = `
      UPDATE tech_stack_recommendations 
      SET ${fields.join(', ')}, updated_at = NOW() 
      WHERE id = $${idx} 
      RETURNING *
    `;
    values.push(id);
    
    const result = await database.query(query, values);
    return result.rows.length > 0 ? new TechStackRecommendation(result.rows[0]) : null;
  }

  // Upsert recommendation (create or update)
  static async upsert(templateId, templateType, data) {
    const existing = await TechStackRecommendation.getByTemplateId(templateId, templateType);
    
    if (existing) {
      return await TechStackRecommendation.update(existing.id, {
        ...data,
        last_analyzed_at: new Date()
      });
    } else {
      return await TechStackRecommendation.create({
        template_id: templateId,
        template_type: templateType,
        ...data
      });
    }
  }

  // Get all recommendations with pagination
  static async getAll(limit = 50, offset = 0, status = null) {
    let query = 'SELECT * FROM tech_stack_recommendations';
    const params = [];
    
    if (status) {
      query += ' WHERE status = $1';
      params.push(status);
    }
    
    query += ' ORDER BY last_analyzed_at DESC LIMIT $' + (params.length + 1) + ' OFFSET $' + (params.length + 2);
    params.push(limit, offset);
    
    const result = await database.query(query, params);
    return result.rows.map(row => new TechStackRecommendation(row));
  }

  // Get recommendations by status
  static async getByStatus(status, limit = 50, offset = 0) {
    const query = `
      SELECT * FROM tech_stack_recommendations 
      WHERE status = $1 
      ORDER BY last_analyzed_at DESC 
      LIMIT $2 OFFSET $3
    `;
    
    const result = await database.query(query, [status, limit, offset]);
    return result.rows.map(row => new TechStackRecommendation(row));
  }

  // Get statistics
  static async getStats() {
    const query = `
      SELECT 
        status,
        COUNT(*) as count,
        AVG(processing_time_ms) as avg_processing_time,
        COUNT(CASE WHEN last_analyzed_at > NOW() - INTERVAL '7 days' THEN 1 END) as recent_analyses
      FROM tech_stack_recommendations 
      GROUP BY status
    `;
    
    const result = await database.query(query);
    return result.rows;
  }

  // Get recommendations needing update (older than specified days)
  static async getStaleRecommendations(daysOld = 30, limit = 100) {
    const query = `
      SELECT tsr.*, 
        COALESCE(t.title, ct.title) as template_title,
        COALESCE(t.type, ct.type) as template_type_name
      FROM tech_stack_recommendations tsr
      LEFT JOIN templates t ON tsr.template_id = t.id AND tsr.template_type = 'default'
      LEFT JOIN custom_templates ct ON tsr.template_id = ct.id AND tsr.template_type = 'custom'
      WHERE tsr.last_analyzed_at < NOW() - INTERVAL '${daysOld} days'
        AND tsr.status = 'completed'
      ORDER BY tsr.last_analyzed_at ASC
      LIMIT $1
    `;
    
    const result = await database.query(query, [limit]);
    return result.rows.map(row => new TechStackRecommendation(row));
  }

  // Delete recommendation
  static async delete(id) {
    const result = await database.query('DELETE FROM tech_stack_recommendations WHERE id = $1', [id]);
    return result.rowCount > 0;
  }

  // Get recommendations with template details
  static async getWithTemplateDetails(limit = 50, offset = 0) {
    const query = `
      SELECT 
        tsr.*,
        COALESCE(t.title, ct.title) as template_title,
        COALESCE(t.type, ct.type) as template_type_name,
        COALESCE(t.category, ct.category) as template_category,
        COALESCE(t.description, ct.description) as template_description
      FROM tech_stack_recommendations tsr
      LEFT JOIN templates t ON tsr.template_id = t.id AND tsr.template_type = 'default'
      LEFT JOIN custom_templates ct ON tsr.template_id = ct.id AND tsr.template_type = 'custom'
      ORDER BY tsr.last_analyzed_at DESC
      LIMIT $1 OFFSET $2
    `;
    
    const result = await database.query(query, [limit, offset]);
    return result.rows.map(row => new TechStackRecommendation(row));
  }
}

module.exports = TechStackRecommendation;
