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

class CustomFeature {
  constructor(data = {}) {
    this.id = data.id;
    this.template_id = data.template_id;
    this.template_type = data.template_type || 'default';
    this.name = data.name;
    this.description = data.description;
    this.complexity = data.complexity;
    this.business_rules = data.business_rules;
    this.technical_requirements = data.technical_requirements;
    this.approved = data.approved;
    this.usage_count = data.usage_count;
    this.created_by_user_session = data.created_by_user_session;
    this.created_at = data.created_at;
    this.updated_at = data.updated_at;
    // Admin approval workflow fields
    this.status = data.status || 'pending';
    this.admin_notes = data.admin_notes;
    this.admin_reviewed_at = data.admin_reviewed_at;
    this.admin_reviewed_by = data.admin_reviewed_by;
    this.canonical_feature_id = data.canonical_feature_id;
    this.similarity_score = data.similarity_score;
  }

  static async getByTemplateId(templateId) {
    const query = `
      SELECT * FROM custom_features
      WHERE template_id = $1
      ORDER BY usage_count DESC, updated_at DESC, name
    `;
    const result = await database.query(query, [templateId]);
    return result.rows.map(r => new CustomFeature(r));
  }

  static async getById(id) {
    const result = await database.query('SELECT * FROM custom_features WHERE id = $1', [id]);
    return result.rows.length ? new CustomFeature(result.rows[0]) : null;
  }

  static async create(data) {
    const id = uuidv4();
    const query = `
      INSERT INTO custom_features (
        id, template_id, template_type, name, description, complexity,
        business_rules, technical_requirements, approved, usage_count, created_by_user_session,
        status, admin_notes, admin_reviewed_at, admin_reviewed_by, canonical_feature_id, similarity_score,
        created_at, updated_at
      ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,DEFAULT,DEFAULT)
      RETURNING *
    `;
    const values = [
      id,
      data.template_id,
      data.template_type || 'default',
      data.name,
      data.description || null,
      data.complexity,
      data.business_rules || null,
      data.technical_requirements || null,
      data.approved ?? false,
      data.usage_count ?? 1,
      data.created_by_user_session || null,
      data.status || 'pending',
      data.admin_notes || null,
      data.admin_reviewed_at || null,
      data.admin_reviewed_by || null,
      data.canonical_feature_id || null,
      data.similarity_score || null,
    ];
    const result = await database.query(query, values);
    return new CustomFeature(result.rows[0]);
  }

  static async update(id, updates) {
    const fields = [];
    const values = [];
    let idx = 1;
    const allowed = [
      'name','description','complexity','business_rules','technical_requirements',
      'approved','usage_count','status','admin_notes','admin_reviewed_at',
      'admin_reviewed_by','canonical_feature_id','similarity_score'
    ];
    for (const k of allowed) {
      if (updates[k] !== undefined) {
        fields.push(`${k} = $${idx++}`);
        values.push(updates[k]);
      }
    }
    if (fields.length === 0) return await CustomFeature.getById(id);
    const query = `UPDATE custom_features SET ${fields.join(', ')}, updated_at = NOW() WHERE id = $${idx} RETURNING *`;
    values.push(id);
    const result = await database.query(query, values);
    return result.rows.length ? new CustomFeature(result.rows[0]) : null;
  }

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

  // Admin workflow methods
  static async getPendingFeatures(limit = 50, offset = 0) {
    const query = `
      SELECT cf.*, t.title as template_title
      FROM custom_features cf
      LEFT JOIN templates t ON cf.template_id = t.id
      WHERE cf.status = 'pending'
      ORDER BY cf.created_at ASC
      LIMIT $1 OFFSET $2
    `;
    const result = await database.query(query, [limit, offset]);
    return result.rows.map(r => new CustomFeature(r));
  }

  static async getFeaturesByStatus(status, limit = 50, offset = 0) {
    const query = `
      SELECT cf.*, t.title as template_title
      FROM custom_features cf
      LEFT JOIN templates t ON cf.template_id = t.id
      WHERE cf.status = $1
      ORDER BY cf.created_at DESC
      LIMIT $2 OFFSET $3
    `;
    const result = await database.query(query, [status, limit, offset]);
    return result.rows.map(r => new CustomFeature(r));
  }

  static async getFeatureStats() {
    const query = `
      SELECT 
        status,
        COUNT(*) as count
      FROM custom_features
      GROUP BY status
    `;
    const result = await database.query(query);
    return result.rows;
  }

  static async reviewFeature(id, reviewData) {
    const { status, admin_notes, canonical_feature_id, admin_reviewed_by } = reviewData;
    
    const updates = {
      status,
      admin_notes,
      admin_reviewed_at: new Date(),
      admin_reviewed_by
    };

    if (canonical_feature_id) {
      updates.canonical_feature_id = canonical_feature_id;
    }

    return await CustomFeature.update(id, updates);
  }

  // Count features for a custom template
  static async countByTemplateId(templateId) {
    const query = `SELECT COUNT(*) as count FROM custom_features WHERE template_id = $1`;
    const result = await database.query(query, [templateId]);
    return parseInt(result.rows[0].count) || 0;
  }

  // Count features for multiple custom templates at once
  static async countByTemplateIds(templateIds) {
    if (!templateIds || templateIds.length === 0) return {};
    
    const placeholders = templateIds.map((_, i) => `$${i + 1}`).join(',');
    const query = `
      SELECT template_id, COUNT(*) as count 
      FROM custom_features 
      WHERE template_id IN (${placeholders})
      GROUP BY template_id
    `;
    
    const result = await database.query(query, templateIds);
    const counts = {};
    result.rows.forEach(row => {
      counts[row.template_id] = parseInt(row.count) || 0;
    });
    
    return counts;
  }

  // Get statistics for admin dashboard
  static async getStats() {
    const query = `
      SELECT 
        status,
        COUNT(*) as count
      FROM custom_features 
      GROUP BY status
    `;
    
    const result = await database.query(query);
    return result.rows.map(row => ({
      status: row.status,
      count: parseInt(row.count) || 0
    }));
  }

  // Get all custom features with pagination
  static async getAllFeatures(limit = 50, offset = 0) {
    const query = `
      SELECT cf.*, t.title as template_title
      FROM custom_features cf
      LEFT JOIN templates t ON cf.template_id = t.id
      ORDER BY cf.created_at DESC
      LIMIT $1 OFFSET $2
    `;
    const result = await database.query(query, [limit, offset]);
    return result.rows.map(r => new CustomFeature(r));
  }
}

module.exports = CustomFeature;
