const moment = require('moment');

class SQLGenerator {
  constructor() {
    this.queryTemplates = {
      rental_trend: this.getRentalTrendQuery,
      rental_average: this.getRentalAverageQuery,
      transaction_trend: this.getTransactionTrendQuery,
      project_summary: this.getProjectSummaryQuery,
      area_comparison: this.getAreaComparisonQuery,
      top_areas: this.getTopAreasQuery,
      property_type_analysis: this.getPropertyTypeAnalysisQuery
    };
  }

  generateSQL(parsedQuery) {
    const { intent, time_period, areas, property_types, room_types, transaction_types } = parsedQuery;
    
    // Determine query type based on intent and context
    let queryType = this.determineQueryType(parsedQuery);
    
    if (!this.queryTemplates[queryType]) {
      throw new Error(`Unsupported query type: ${queryType}`);
    }

    return this.queryTemplates[queryType](parsedQuery);
  }

  determineQueryType(parsedQuery) {
    const { intent, original_query } = parsedQuery;
    const query = original_query.toLowerCase();

    if (query.includes('rental') || query.includes('rent')) {
      if (intent === 'trend') return 'rental_trend';
      if (intent === 'average') return 'rental_average';
    }

    if (query.includes('transaction') || query.includes('sales')) {
      if (intent === 'trend') return 'transaction_trend';
    }

    if (query.includes('project') && intent === 'summary') {
      return 'project_summary';
    }

    if (query.includes('top') || query.includes('best')) {
      return 'top_areas';
    }

    if (intent === 'compare') {
      return 'area_comparison';
    }

    return 'rental_trend'; // default
  }

  getRentalTrendQuery(parsedQuery) {
    const { time_period, areas, property_types, room_types } = parsedQuery;
    
    let sql = `
      SELECT 
        DATE_FORMAT(start_date, '%Y-%m') as month,
        AVG(annual_amount) as avg_price,
        COUNT(*) as transaction_count,
        AVG(actual_area) as avg_area
      FROM rents 
      WHERE 1=1
    `;

    const params = [];

    // Time filter
    if (time_period && time_period.startDate) {
      sql += ` AND start_date >= ?`;
      params.push(time_period.startDate);
    }

    // Area filter
    if (areas && areas.length > 0) {
      const areaPlaceholders = areas.map(() => '?').join(',');
      sql += ` AND area_en IN (${areaPlaceholders})`;
      params.push(...areas);
    }

    // Property type filter
    if (property_types && property_types.length > 0) {
      const typePlaceholders = property_types.map(() => '?').join(',');
      sql += ` AND prop_sub_type_en IN (${typePlaceholders})`;
      params.push(...property_types);
    }

    sql += ` GROUP BY DATE_FORMAT(start_date, '%Y-%m') ORDER BY month`;

    return { sql, params };
  }

  getRentalAverageQuery(parsedQuery) {
    const { time_period, areas, property_types, room_types } = parsedQuery;
    
    let sql = `
      SELECT 
        AVG(annual_amount) as avg_price,
        COUNT(*) as total_count,
        MIN(annual_amount) as min_price,
        MAX(annual_amount) as max_price,
        AVG(actual_area) as avg_area
      FROM rents 
      WHERE 1=1
    `;

    const params = [];

    if (time_period && time_period.startDate) {
      sql += ` AND start_date >= ?`;
      params.push(time_period.startDate);
    }

    if (areas && areas.length > 0) {
      const areaPlaceholders = areas.map(() => '?').join(',');
      sql += ` AND area_en IN (${areaPlaceholders})`;
      params.push(...areas);
    }

    if (property_types && property_types.length > 0) {
      const typePlaceholders = property_types.map(() => '?').join(',');
      sql += ` AND prop_sub_type_en IN (${typePlaceholders})`;
      params.push(...property_types);
    }

    return { sql, params };
  }

  getTransactionTrendQuery(parsedQuery) {
    const { time_period, areas, property_types } = parsedQuery;
    
    let sql = `
      SELECT 
        DATE_FORMAT(instance_date, '%Y-%m') as month,
        AVG(trans_value) as avg_value,
        COUNT(*) as transaction_count,
        AVG(actual_area) as avg_area
      FROM transactions 
      WHERE 1=1
    `;

    const params = [];

    if (time_period && time_period.startDate) {
      sql += ` AND instance_date >= ?`;
      params.push(time_period.startDate);
    }

    if (areas && areas.length > 0) {
      const areaPlaceholders = areas.map(() => '?').join(',');
      sql += ` AND area_en IN (${areaPlaceholders})`;
      params.push(...areas);
    }

    if (property_types && property_types.length > 0) {
      const typePlaceholders = property_types.map(() => '?').join(',');
      sql += ` AND prop_type_en IN (${typePlaceholders})`;
      params.push(...property_types);
    }

    sql += ` GROUP BY DATE_FORMAT(instance_date, '%Y-%m') ORDER BY month`;

    return { sql, params };
  }

  getProjectSummaryQuery(parsedQuery) {
    const { time_period } = parsedQuery;
    
    let sql = `
      SELECT 
        project_en,
        developer_en,
        project_status,
        percent_completed,
        project_value,
        area_en,
        cnt_unit,
        cnt_villa,
        cnt_land
      FROM projects 
      WHERE 1=1
    `;

    const params = [];

    if (time_period && time_period.startDate) {
      sql += ` AND start_date >= ?`;
      params.push(time_period.startDate);
    }

    sql += ` ORDER BY project_value DESC LIMIT 10`;

    return { sql, params };
  }

  getTopAreasQuery(parsedQuery) {
    const { time_period, transaction_types } = parsedQuery;
    
    let sql = `
      SELECT 
        area_en,
        COUNT(*) as transaction_count,
        AVG(annual_amount) as avg_price,
        AVG(actual_area) as avg_area
      FROM rents 
      WHERE 1=1
    `;

    const params = [];

    if (time_period && time_period.startDate) {
      sql += ` AND start_date >= ?`;
      params.push(time_period.startDate);
    }

    sql += ` GROUP BY area_en ORDER BY transaction_count DESC LIMIT 5`;

    return { sql, params };
  }

  getAreaComparisonQuery(parsedQuery) {
    const { time_period, areas, property_types } = parsedQuery;
    
    let sql = `
      SELECT 
        area_en,
        AVG(annual_amount) as avg_price,
        COUNT(*) as transaction_count,
        AVG(actual_area) as avg_area
      FROM rents 
      WHERE 1=1
    `;

    const params = [];

    if (time_period && time_period.startDate) {
      sql += ` AND start_date >= ?`;
      params.push(time_period.startDate);
    }

    if (areas && areas.length > 0) {
      const areaPlaceholders = areas.map(() => '?').join(',');
      sql += ` AND area_en IN (${areaPlaceholders})`;
      params.push(...areas);
    }

    if (property_types && property_types.length > 0) {
      const typePlaceholders = property_types.map(() => '?').join(',');
      sql += ` AND prop_sub_type_en IN (${typePlaceholders})`;
      params.push(...property_types);
    }

    sql += ` GROUP BY area_en ORDER BY avg_price DESC`;

    return { sql, params };
  }

  getPropertyTypeAnalysisQuery(parsedQuery) {
    const { time_period, areas } = parsedQuery;
    
    let sql = `
      SELECT 
        prop_sub_type_en,
        COUNT(*) as count,
        AVG(annual_amount) as avg_price,
        AVG(actual_area) as avg_area
      FROM rents 
      WHERE 1=1
    `;

    const params = [];

    if (time_period && time_period.startDate) {
      sql += ` AND start_date >= ?`;
      params.push(time_period.startDate);
    }

    if (areas && areas.length > 0) {
      const areaPlaceholders = areas.map(() => '?').join(',');
      sql += ` AND area_en IN (${areaPlaceholders})`;
      params.push(...areas);
    }

    sql += ` GROUP BY prop_sub_type_en ORDER BY count DESC`;

    return { sql, params };
  }
}

module.exports = SQLGenerator;

