const express = require('express');
const router = express.Router();
const moment = require('moment');

const DubaiRealEstateParser = require('../services/nlpService');
const SQLGenerator = require('../services/sqlGenerator');
const ContextAwareSQLGenerator = require('../services/contextAwareSQLGenerator');
const ChartFormatter = require('../services/chartFormatter');
const ContextManager = require('../services/contextManager');
const QueryTemplates = require('../services/queryTemplates');
const database = require('../models/database');
const { validateQuery } = require('../middleware/validation');

const nlpParser = new DubaiRealEstateParser();
const sqlGenerator = new SQLGenerator();
const contextAwareSQLGenerator = new ContextAwareSQLGenerator();
const chartFormatter = new ChartFormatter();
const contextManager = new ContextManager();
const templates = new QueryTemplates();

// Main query endpoint
router.post('/query', validateQuery, async (req, res) => {
  try {
    const { query, sessionId } = req.validatedData;
    
    console.log(`🔍 Processing query: "${query}"`);
    
    // Step 1: Parse the natural language query
    const parsedQuery = await nlpParser.parseQuery(query);
    console.log('📝 Parsed query:', parsedQuery);
    
    // Step 2: Generate SQL query with context awareness
    const sqlQuery = await contextAwareSQLGenerator.generateSQL(parsedQuery, sessionId);
    console.log('🗄️ Generated SQL:', sqlQuery.sql);
    
    // Step 3: Execute SQL query
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    console.log(`📊 Query returned ${sqlResult.length} rows`);
    
    // Step 4: Format response for Chart.js
    // Use merged context if available (for follow-up queries)
    const contextForFormatter = sqlQuery.mergedContext || parsedQuery;
    const response = chartFormatter.formatResponse(contextForFormatter, sqlResult, sqlQuery);
    
    res.json(response);
    
  } catch (error) {
    console.error('❌ Query processing error:', error);
    
    res.status(500).json({
      success: false,
      message: 'Failed to process query',
      error: process.env.NODE_ENV === 'development' ? error.message : 'Internal server error'
    });
  }
});

// Specific query endpoints for the 10 questions
// Q1-3: Rental price trend with context awareness
router.post('/queries/rental-trend', async (req, res) => {
  try {
    const { area = 'business bay', sessionId, refinement } = req.body;
    const query = `Give me the last 6 months rental price trend for ${area}`;
    
    const parsedQuery = await nlpParser.parseQuery(query);
    
    // Apply refinement if provided
    if (refinement) {
      parsedQuery.refinements = contextManager.extractRefinements(refinement);
    }
    
    const sqlQuery = await contextAwareSQLGenerator.generateSQL(parsedQuery, sessionId);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    const response = chartFormatter.formatResponse(parsedQuery, sqlResult, sqlQuery);
    
    res.json(response);
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

// Q4: Brief about the Project
router.get('/queries/project-summary-detail', async (req, res) => {
  try {
    const params = { startDate: moment().subtract(6, 'months').format('YYYY-MM-DD') };
    const sqlQuery = templates.getTemplate('project_transaction_summary', params);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    
    res.json({
      success: true,
      data: {
        text: 'Transaction summary for projects',
        visualizations: chartFormatter.createVisualizations(sqlResult, { intent: 'summary' }),
        cards: chartFormatter.createCards(sqlResult, { intent: 'summary' })
      }
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

// Q5: Fast moving projects
router.get('/queries/fast-moving-projects', async (req, res) => {
  try {
    const params = { startDate: moment().subtract(6, 'months').format('YYYY-MM-DD') };
    const sqlQuery = templates.getTemplate('fast_moving_projects', params);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    
    res.json({
      success: true,
      data: {
        text: 'Fast moving projects in last 6 months',
        visualizations: chartFormatter.createVisualizations(sqlResult, { intent: 'compare' }),
        cards: chartFormatter.createCards(sqlResult, { intent: 'compare' })
      }
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

// Q6: Off-plan uptick areas
router.get('/queries/offplan-uptick', async (req, res) => {
  try {
    const params = { startDate: moment().subtract(6, 'months').format('YYYY-MM-DD') };
    const sqlQuery = templates.getTemplate('offplan_uptick_areas', params);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    
    res.json({
      success: true,
      data: {
        text: 'Areas seeing uptick in off-plan projects',
        visualizations: chartFormatter.createVisualizations(sqlResult, { intent: 'compare' }),
        cards: chartFormatter.createCards(sqlResult, { intent: 'compare' })
      }
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

// Predefined query endpoints for common questions
router.get('/queries/rental-trend/:area?', async (req, res) => {
  try {
    const area = req.params.area || 'business bay';
    const query = `Give me the last 6 months rental price trend for ${area}`;
    
    const parsedQuery = await nlpParser.parseQuery(query);
    const sqlQuery = sqlGenerator.generateSQL(parsedQuery);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    const response = chartFormatter.formatResponse(parsedQuery, sqlResult, sqlQuery);
    
    res.json(response);
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

router.get('/queries/top-areas', async (req, res) => {
  try {
    const query = 'Which area is having more rental transactions?';
    
    const parsedQuery = await nlpParser.parseQuery(query);
    const sqlQuery = sqlGenerator.generateSQL(parsedQuery);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    const response = chartFormatter.formatResponse(parsedQuery, sqlResult, sqlQuery);
    
    res.json(response);
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

router.get('/queries/project-summary', async (req, res) => {
  try {
    const query = 'Brief about the Project';
    
    const parsedQuery = await nlpParser.parseQuery(query);
    const sqlQuery = sqlGenerator.generateSQL(parsedQuery);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    const response = chartFormatter.formatResponse(parsedQuery, sqlResult, sqlQuery);
    
    res.json(response);
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

router.get('/queries/commercial-leasing', async (req, res) => {
  try {
    const query = 'Top 5 areas for Commercial leasing and why?';
    
    const parsedQuery = await nlpParser.parseQuery(query);
    const sqlQuery = sqlGenerator.generateSQL(parsedQuery);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    const response = chartFormatter.formatResponse(parsedQuery, sqlResult, sqlQuery);
    
    res.json(response);
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

router.get('/queries/residential-leasing', async (req, res) => {
  try {
    const query = 'Top 5 areas for Residential leasing and why?';
    
    const parsedQuery = await nlpParser.parseQuery(query);
    const sqlQuery = sqlGenerator.generateSQL(parsedQuery);
    const sqlResult = await database.query(sqlQuery.sql, sqlQuery.params);
    const response = chartFormatter.formatResponse(parsedQuery, sqlResult, sqlQuery);
    
    res.json(response);
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

// Database info endpoint
router.get('/database/info', async (req, res) => {
  try {
    const tables = ['transactions', 'rents', 'projects', 'buildings', 'lands', 'valuations', 'brokers'];
    const info = {};
    
    for (const table of tables) {
      try {
        const [countResult] = await database.query(`SELECT COUNT(*) as count FROM ${table}`);
        info[table] = {
          count: countResult[0].count,
          status: 'available'
        };
      } catch (error) {
        info[table] = {
          count: 0,
          status: 'error',
          error: error.message
        };
      }
    }
    
    res.json({
      success: true,
      data: {
        database: process.env.DB_NAME || 'dubai_dld',
        tables: info,
        timestamp: new Date().toISOString()
      }
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

// Available queries endpoint
router.get('/queries/available', (req, res) => {
  res.json({
    success: true,
    data: {
      predefined_queries: [
        {
          endpoint: '/api/queries/rental-trend/:area',
          description: 'Get rental price trend for a specific area',
          example: '/api/queries/rental-trend/business-bay'
        },
        {
          endpoint: '/api/queries/top-areas',
          description: 'Get top areas with most rental transactions'
        },
        {
          endpoint: '/api/queries/project-summary',
          description: 'Get project summary and statistics'
        },
        {
          endpoint: '/api/queries/commercial-leasing',
          description: 'Get top areas for commercial leasing'
        },
        {
          endpoint: '/api/queries/residential-leasing',
          description: 'Get top areas for residential leasing'
        }
      ],
      custom_queries: {
        endpoint: '/api/query',
        method: 'POST',
        description: 'Process custom natural language queries',
        examples: [
          'Give me the last 6 months rental price trend for Business Bay',
          'Which area is having more rental transactions?',
          'Top 5 areas for Commercial leasing and why?',
          'Avg price of 3BHK apartment by area in last 6 months',
          'Brief about the Project'
        ]
      }
    }
  });
});

// Recent transactions endpoint with filters
router.get('/transactions/recent', async (req, res) => {
  try {
    const { 
      area_name, 
      property_type, 
      size, 
      size_min, 
      size_max,
      beds, 
      project, 
      limit 
    } = req.query;
    
    // Validate limit only if provided; no upper cap enforced by API
    let limitNum = undefined;
    if (limit !== undefined && limit !== null && `${limit}`.trim() !== '') {
      const parsed = parseInt(limit, 10);
      if (isNaN(parsed) || parsed < 1) {
        return res.status(400).json({
          success: false,
          message: 'Limit must be a positive integer when provided'
        });
      }
      limitNum = parsed;
    }
    
    // Build SQL query with optional filters
    let sql = `
      SELECT *
      FROM transactions
      WHERE 1=1
    `;
    const params = [];
    
    // Apply filters (case-insensitive matching where applicable)
    if (area_name && area_name.trim() !== '') {
      sql += ' AND LOWER(area_en) LIKE ?';
      params.push(`%${area_name.toLowerCase().trim()}%`);
    }
    
    if (property_type && property_type.trim() !== '' && property_type !== 'all') {
      sql += ' AND (LOWER(prop_type_en) LIKE ? OR LOWER(prop_sb_type_en) LIKE ?)';
      const propType = `%${property_type.toLowerCase().trim()}%`;
      params.push(propType, propType);
    }
    
    // Size filtering: support size_min/size_max. Keep legacy 'size' as upper bound
    const minNum = size_min !== undefined ? parseFloat(size_min) : undefined;
    const maxNum = size_max !== undefined ? parseFloat(size_max) : (size !== undefined ? parseFloat(size) : undefined);
    const hasMin = minNum !== undefined && !isNaN(minNum);
    const hasMax = maxNum !== undefined && !isNaN(maxNum);
    if (hasMin && hasMax) {
      sql += ' AND actual_area BETWEEN ? AND ?';
      params.push(minNum, maxNum);
    } else if (hasMin) {
      sql += ' AND actual_area >= ?';
      params.push(minNum);
    } else if (hasMax) {
      sql += ' AND actual_area <= ?';
      params.push(maxNum);
    }
    
    if (beds && beds !== 'all' && beds !== '') {
      const bedsStr = beds.toString().trim();
      // Match beds - handle formats like "3 b/r", "3.0", "3", "studio"
      if (bedsStr.toLowerCase() === 'studio') {
        sql += ' AND LOWER(rooms_en) = ?';
        params.push('studio');
      } else if (bedsStr.toLowerCase() === 'null' || bedsStr === '') {
        sql += ' AND (rooms_en IS NULL OR rooms_en = "")';
      } else {
        sql += ' AND (rooms_en LIKE ? OR rooms_en = ? OR rooms_en = ?)';
        params.push(`%${bedsStr}%`, bedsStr, `${bedsStr}.0`);
      }
    }
    
    if (project && project.trim() !== '' && project !== 'all') {
      sql += ' AND (LOWER(project_en) LIKE ? OR LOWER(master_project_en) LIKE ?)';
      const projectName = `%${project.toLowerCase().trim()}%`;
      params.push(projectName, projectName);
    }
    
    // Order by most recent first; apply LIMIT only if provided
    sql += ' ORDER BY instance_date DESC';
    if (limitNum !== undefined) {
      sql += ` LIMIT ${limitNum}`;
    }
    
    console.log(`🔍 Fetching recent transactions with filters:`, { 
      area_name, property_type, size, size_min, size_max, beds, project, limit: limitNum 
    });
    
    const transactions = await database.query(sql, params);
    
    res.json({
      success: true,
      data: {
        transactions: transactions,
        count: transactions.length,
        filters: {
          area_name: area_name || null,
          property_type: property_type || null,
          size: size || null,
          beds: beds || null,
          project: project || null,
          limit: limitNum ?? null
        }
      }
    });
    
  } catch (error) {
    console.error('❌ Transactions query error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to retrieve transactions',
      error: process.env.NODE_ENV === 'development' ? error.message : 'Internal server error'
    });
  }
});

module.exports = router;
