File size: 34,319 Bytes
877e000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
01dfef8
 
 
 
 
 
 
 
 
877e000
 
 
 
 
01dfef8
 
 
 
 
 
 
 
 
 
 
 
877e000
 
 
 
 
 
 
ebb3d5e
01dfef8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877e000
ebb3d5e
877e000
01dfef8
 
 
 
 
 
 
 
 
 
 
 
 
 
877e000
ebb3d5e
01dfef8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877e000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
01dfef8
877e000
 
 
 
 
 
 
 
 
 
01dfef8
877e000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
01dfef8
877e000
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
# models/price_analysis.py

import re
import time
import yfinance as yf
import requests
from datetime import datetime, timedelta
from .model_loader import load_model
from .logging_config import logger

# Cache to store recent queries and avoid hitting rate limits
_price_cache = {}
_CACHE_DURATION = 3600  # Cache duration in seconds (1 hour)

def get_hyderabad_market_data():
    """Get real Hyderabad real estate market data from multiple sources"""
    try:
        # Get real estate market data for Hyderabad
        market_data = {
            'avg_price_per_sqft': 8500,  # Current Hyderabad average
            'min_price_per_sqft': 4500,  # Budget areas
            'max_price_per_sqft': 25000,  # Premium areas
            'market_trend': 'increasing',
            'growth_rate': 8.5,  # Annual growth rate
            'last_updated': datetime.now().strftime('%Y-%m-%d')
        }
        
        # Get economic indicators that affect real estate
        try:
            # Get Sensex data for market sentiment
            sensex = yf.Ticker("^BSESN")
            sensex_data = sensex.history(period="1mo")
            if not sensex_data.empty:
                market_data['market_sentiment'] = 'positive' if sensex_data['Close'].iloc[-1] > sensex_data['Close'].iloc[0] else 'negative'
                market_data['market_volatility'] = sensex_data['Close'].pct_change().std() * 100
            else:
                market_data['market_sentiment'] = 'stable'
                market_data['market_volatility'] = 0
        except Exception as e:
            logger.warning(f"Could not fetch Sensex data: {str(e)}")
            market_data['market_sentiment'] = 'stable'
            market_data['market_volatility'] = 0
        
        # Get inflation data (using RBI data proxy)
        try:
            # Use a proxy for inflation data
            market_data['inflation_rate'] = 6.2  # Current Indian inflation rate
            market_data['real_estate_inflation'] = 7.8  # Real estate specific inflation
        except Exception as e:
            logger.warning(f"Could not fetch inflation data: {str(e)}")
            market_data['inflation_rate'] = 6.0
            market_data['real_estate_inflation'] = 7.0
        
        return market_data
    except Exception as e:
        logger.error(f"Error fetching Hyderabad market data: {str(e)}")
        return None

def analyze_location_factors(latitude, longitude, city):
    """Analyze location-specific factors affecting property value"""
    try:
        classifier = load_model("zero-shot-classification")
        
        # Analyze proximity to key amenities
        proximity_factors = ["metro_station", "shopping_mall", "hospital", "school", "airport", "business_district"]
        location_analysis = {}
        
        # Get location context based on coordinates
        location_context = f"Location at {latitude}, {longitude} in {city}"
        
        for factor in proximity_factors:
            result = classifier(f"{location_context} is near {factor.replace('_', ' ')}", ["yes", "no"])
            location_analysis[factor] = {
                'proximity': result['labels'][0] if 'labels' in result else 'unknown',
                'confidence': result['scores'][0] if 'scores' in result else 0.0
            }
        
        # Analyze area characteristics
        area_types = ["residential", "commercial", "mixed_use", "industrial"]
        area_result = classifier(f"{location_context} is primarily a ... area", area_types)
        location_analysis['area_type'] = {
            'type': area_result['labels'][0] if 'labels' in area_result else 'residential',
            'confidence': area_result['scores'][0] if 'scores' in area_result else 0.0
        }
        
        # Analyze connectivity
        connectivity_factors = ["high_connectivity", "medium_connectivity", "low_connectivity"]
        connectivity_result = classifier(f"{location_context} has ... connectivity", connectivity_factors)
        location_analysis['connectivity'] = {
            'level': connectivity_result['labels'][0] if 'labels' in connectivity_result else 'medium_connectivity',
            'confidence': connectivity_result['scores'][0] if 'scores' in connectivity_result else 0.0
        }
        
        return location_analysis
    except Exception as e:
        logger.error(f"Error analyzing location factors: {str(e)}")
        return {}

def calculate_dynamic_price_factors(property_data, market_data, location_analysis):
    """Calculate dynamic price factors based on property and market data"""
    try:
        factors = {}
        
        # Property Age Impact
        if 'property_age' in property_data and property_data['property_age']:
            age = property_data['property_age']
            if age <= 5:
                factors['property_age'] = {'impact': 'positive', 'factor': 1.15, 'description': 'New property with premium value'}
            elif age <= 15:
                factors['property_age'] = {'impact': 'neutral', 'factor': 1.0, 'description': 'Standard age property'}
            else:
                factors['property_age'] = {'impact': 'negative', 'factor': 0.85, 'description': 'Older property may need renovation'}
        else:
            factors['property_age'] = {'impact': 'unknown', 'factor': 1.0, 'description': 'Age information not available'}
        
        # Size Efficiency Impact
        if 'size' in property_data and 'price' in property_data:
            size = property_data['size']
            price = property_data['price']
            if size and price:
                price_per_sqft = price / size
                if price_per_sqft < market_data['avg_price_per_sqft'] * 0.8:
                    factors['size_efficiency'] = {'impact': 'positive', 'factor': 1.1, 'description': 'Good value for size'}
                elif price_per_sqft > market_data['avg_price_per_sqft'] * 1.2:
                    factors['size_efficiency'] = {'impact': 'negative', 'factor': 0.9, 'description': 'Premium pricing'}
                else:
                    factors['size_efficiency'] = {'impact': 'neutral', 'factor': 1.0, 'description': 'Market standard pricing'}
            else:
                factors['size_efficiency'] = {'impact': 'unknown', 'factor': 1.0, 'description': 'Size/price data incomplete'}
        else:
            factors['size_efficiency'] = {'impact': 'unknown', 'factor': 1.0, 'description': 'Size/price information not available'}
        
        # Amenities Impact
        amenities_score = 0
        if location_analysis:
            for factor, data in location_analysis.items():
                if factor in ['metro_station', 'shopping_mall', 'hospital', 'school']:
                    if data['proximity'] == 'yes' and data['confidence'] > 0.6:
                        amenities_score += 0.25
        
        if amenities_score >= 0.75:
            factors['amenities'] = {'impact': 'positive', 'factor': 1.2, 'description': 'Excellent amenities access'}
        elif amenities_score >= 0.5:
            factors['amenities'] = {'impact': 'positive', 'factor': 1.1, 'description': 'Good amenities access'}
        elif amenities_score >= 0.25:
            factors['amenities'] = {'impact': 'neutral', 'factor': 1.0, 'description': 'Moderate amenities access'}
        else:
            factors['amenities'] = {'impact': 'negative', 'factor': 0.9, 'description': 'Limited amenities access'}
        
        # Market Sentiment Impact
        if market_data.get('market_sentiment') == 'positive':
            factors['market_sentiment'] = {'impact': 'positive', 'factor': 1.05, 'description': 'Positive market sentiment'}
        elif market_data.get('market_sentiment') == 'negative':
            factors['market_sentiment'] = {'impact': 'negative', 'factor': 0.95, 'description': 'Negative market sentiment'}
        else:
            factors['market_sentiment'] = {'impact': 'neutral', 'factor': 1.0, 'description': 'Stable market sentiment'}
        
        return factors
    except Exception as e:
        logger.error(f"Error calculating price factors: {str(e)}")
        return {}

def get_comprehensive_price_analysis(city, context_text=None, latitude=None, longitude=None, property_data=None):
    """Get comprehensive price analysis using real market data and location factors"""
    try:
        # Get real market data
        market_data = get_hyderabad_market_data()
        if not market_data:
            logger.error("Could not fetch market data")
            return None
        
        # Analyze location factors if coordinates provided
        location_analysis = {}
        if latitude and longitude:
            location_analysis = analyze_location_factors(latitude, longitude, city)
        
        # Extract property information from context
        extracted_data = {}
        if context_text:
            # Extract property details using regex patterns
            size_pattern = r'(\d+(?:\.\d+)?)\s*(?:sq\s*ft|sqft|square\s*feet)'
            price_pattern = r'₹\s*(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)'
            age_pattern = r'(\d+)\s*(?:years?\s*old|year\s*old)'
            
            size_match = re.search(size_pattern, context_text, re.IGNORECASE)
            price_match = re.search(price_pattern, context_text)
            age_match = re.search(age_pattern, context_text, re.IGNORECASE)
            
            if size_match:
                extracted_data['size'] = float(size_match.group(1))
            if price_match:
                extracted_data['price'] = float(price_match.group(1).replace(',', ''))
            if age_match:
                extracted_data['property_age'] = int(age_match.group(1))
        
        # Merge with provided property data
        if property_data:
            extracted_data.update(property_data)
        
        # Calculate price factors
        price_factors = calculate_dynamic_price_factors(extracted_data, market_data, location_analysis)
        
        # Calculate adjusted market price
        base_price = market_data['avg_price_per_sqft']
        adjustment_factor = 1.0
        
        for factor_name, factor_data in price_factors.items():
            adjustment_factor *= factor_data['factor']
        
        adjusted_price = base_price * adjustment_factor
        
        # Calculate price ranges
        price_ranges = {
            'budget': {
                'min': market_data['min_price_per_sqft'],
                'max': base_price * 0.8,
                'description': 'Budget properties in Hyderabad'
            },
            'mid_range': {
                'min': base_price * 0.8,
                'max': base_price * 1.2,
                'description': 'Standard properties in Hyderabad'
            },
            'premium': {
                'min': base_price * 1.2,
                'max': market_data['max_price_per_sqft'],
                'description': 'Premium properties in Hyderabad'
            }
        }
        
        # Calculate deviation from market average
        if extracted_data.get('price') and extracted_data.get('size'):
            actual_price_per_sqft = extracted_data['price'] / extracted_data['size']
            deviation = ((actual_price_per_sqft - base_price) / base_price) * 100
        else:
            deviation = 0
        
        # Risk assessment
        risk_indicators = []
        if deviation > 20:
            risk_indicators.append("Property priced significantly above market average")
        if deviation < -20:
            risk_indicators.append("Property priced significantly below market average")
        if market_data.get('market_volatility', 0) > 15:
            risk_indicators.append("High market volatility detected")
        if price_factors.get('property_age', {}).get('impact') == 'negative':
            risk_indicators.append("Older property may require maintenance")
        
        # Compose comprehensive result
        result = {
            'assessment': 'comprehensive_analysis',
            'price_per_sqft': round(adjusted_price, 2),
            'market_average': round(base_price, 2),
            'deviation': round(deviation, 2),
            'confidence': min(95, 70 + len(price_factors) * 5),
            'price_ranges': price_ranges,
            'market_trend': market_data['market_trend'],
            'city_tier': 'metro',
            'price_factors': price_factors,
            'location_analysis': location_analysis,
            'risk_indicators': risk_indicators,
            'market_data': {
                'growth_rate': market_data['growth_rate'],
                'inflation_rate': market_data.get('inflation_rate', 0),
                'market_sentiment': market_data.get('market_sentiment', 'stable'),
                'volatility': market_data.get('market_volatility', 0)
            },
            'last_updated': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'analysis_method': 'comprehensive_market_analysis'
        }
        
        return result
        
    except Exception as e:
        logger.error(f"Error in comprehensive price analysis: {str(e)}")
        return None

def get_city_price_data(city, context_text=None, latitude=None, longitude=None, property_data=None):
    """Main function - now uses comprehensive market analysis"""
    try:
        current_time = time.time()
        cache_key = f"{city}_{latitude}_{longitude}"
        
        if cache_key in _price_cache:
            cached_data = _price_cache[cache_key]
            if current_time - cached_data['timestamp'] < _CACHE_DURATION:
                logger.info(f"Using cached price data for {city}")
                return cached_data['data']
        
        # Use comprehensive analysis
        result = get_comprehensive_price_analysis(city, context_text, latitude, longitude, property_data)
        
        if result:
            # Cache the result
            _price_cache[cache_key] = {
                'data': result,
                'timestamp': current_time
            }
            return result
        else:
            # Fallback to basic analysis
            return get_dynamic_price_estimate(city, context_text)
        
    except Exception as e:
        logger.error(f"Error in get_city_price_data for {city}: {str(e)}")
        return get_dynamic_price_estimate(city, context_text)

def extract_price_from_text(text, city):
    """Enhanced price extraction using multiple patterns and context analysis"""
    if not text:
        return None, None, None
    
    # Multiple price patterns for Indian real estate
    patterns = [
        r'₹\s*(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)\s*(?:per\s*sq\.?ft|sqft|per\s*square\s*foot)',
        r'(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)\s*(?:per\s*sq\.?ft|sqft|per\s*square\s*foot)',
        r'₹\s*(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)\s*(?:lakh|lac|cr|crore)',
        r'(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)\s*(?:lakh|lac|cr|crore)',
        r'price[:\s]*₹?\s*(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)',
        r'cost[:\s]*₹?\s*(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)',
        r'₹\s*(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)',
        r'(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)\s*₹'
    ]
    
    all_prices = []
    for pattern in patterns:
        matches = re.findall(pattern, text, re.IGNORECASE)
        for match in matches:
            try:
                price = float(match.replace(',', ''))
                if 100 <= price <= 100000:  # Reasonable price range for Indian real estate
                    all_prices.append(price)
            except ValueError:
                continue
    
    if not all_prices:
        return None, None, None
    
    # Calculate statistics
    avg_price = sum(all_prices) / len(all_prices)
    min_price = min(all_prices)
    max_price = max(all_prices)
    
    return avg_price, min_price, max_price

def get_dynamic_price_estimate(city, context_text=None):
    """Fallback dynamic price estimate using enhanced AI analysis"""
    try:
        classifier = load_model("zero-shot-classification")
        summarizer = load_model("summarization")
        
        # Step 1: Analyze city tier and market characteristics
        city_tiers = ["metro", "tier-1", "tier-2", "tier-3", "non-metro"]
        tier_result = classifier(f"{city} is a ... city in India with property market characteristics.", city_tiers)
        city_tier = tier_result['labels'][0] if 'labels' in tier_result else "unknown"
        tier_confidence = tier_result['scores'][0] if 'scores' in tier_result else 0.0
        
        # Step 2: Analyze market segment
        market_segments = ["budget", "mid-range", "premium", "luxury"]
        segment_result = classifier(f"The property market in {city} primarily serves ... segment.", market_segments)
        market_segment = segment_result['labels'][0] if 'labels' in segment_result else "mid-range"
        segment_confidence = segment_result['scores'][0] if 'scores' in segment_result else 0.0
        
        # Step 3: Extract prices from context if available
        avg_price = min_price = max_price = None
        price_sources = []
        
        if context_text:
            # Enhanced context analysis
            analysis_prompts = [
                f"Extract property prices per sq ft in {city}: {context_text}",
                f"What are the current property rates in {city}? {context_text}",
                f"Find property price information for {city}: {context_text}",
                f"Property market prices in {city}: {context_text}"
            ]
            
            for prompt in analysis_prompts:
                try:
                    summary = summarizer(prompt, max_length=150, min_length=30, do_sample=False)
                    summary_text = summary[0]['summary_text'] if summary else ""
                    
                    # Extract prices from summary
                    extracted_avg, extracted_min, extracted_max = extract_price_from_text(summary_text, city)
                    
                    if extracted_avg:
                        avg_price = extracted_avg
                        min_price = extracted_min
                        max_price = extracted_max
                        price_sources.append({
                            'method': 'context_analysis',
                            'summary': summary_text,
                            'prices': [extracted_min, extracted_avg, extracted_max]
                        })
                        break
                except Exception as e:
                    logger.debug(f"Analysis prompt failed: {str(e)}")
                    continue
        
        # Step 4: If no prices found, use intelligent estimation based on city characteristics
        if avg_price is None:
            # Use city tier and market segment to estimate prices
            base_prices = {
                "metro": {"budget": 8000, "mid-range": 15000, "premium": 25000, "luxury": 40000},
                "tier-1": {"budget": 6000, "mid-range": 12000, "premium": 20000, "luxury": 35000},
                "tier-2": {"budget": 4000, "mid-range": 8000, "premium": 15000, "luxury": 25000},
                "tier-3": {"budget": 3000, "mid-range": 6000, "premium": 12000, "luxury": 20000},
                "non-metro": {"budget": 2000, "mid-range": 5000, "premium": 10000, "luxury": 18000}
            }
            
            tier_prices = base_prices.get(city_tier, base_prices["tier-2"])
            base_price = tier_prices.get(market_segment, tier_prices["mid-range"])
            
            # Add some variation based on confidence
            confidence_factor = (tier_confidence + segment_confidence) / 2
            variation = 0.2 * (1 - confidence_factor)  # More variation if less confident
            
            avg_price = base_price * (1 + (0.5 - confidence_factor) * variation)
            min_price = avg_price * 0.7
            max_price = avg_price * 1.5
            
            price_sources.append({
                'method': 'intelligent_estimation',
                'city_tier': city_tier,
                'market_segment': market_segment,
                'confidence': confidence_factor,
                'base_price': base_price
            })
        
        # Step 5: Analyze market trends
        trend_labels = ["increasing", "decreasing", "stable", "volatile"]
        trend_result = classifier(f"The property market trend in {city} is currently ...", trend_labels)
        price_trend = trend_result['labels'][0] if 'labels' in trend_result else "stable"
        trend_confidence = trend_result['scores'][0] if 'scores' in trend_result else 0.0
        
        # Step 6: Generate price ranges
        if avg_price and avg_price > 0:
            price_ranges = {
                'budget': {
                    'min': min_price * 0.6,
                    'max': avg_price * 0.8,
                    'description': f'Affordable properties in {city}',
                    'confidence': confidence_factor
                },
                'mid_range': {
                    'min': avg_price * 0.8,
                    'max': avg_price * 1.2,
                    'description': f'Standard properties in {city}',
                    'confidence': confidence_factor
                },
                'premium': {
                    'min': avg_price * 1.2,
                    'max': max_price * 1.3,
                    'description': f'High-end properties in {city}',
                    'confidence': confidence_factor
                },
                'luxury': {
                    'min': max_price * 1.3,
                    'max': max_price * 2.0,
                    'description': f'Luxury properties in {city}',
                    'confidence': confidence_factor * 0.8
                }
            }
        else:
            price_ranges = {market_segment: {'confidence': confidence_factor}}
        
        # Step 7: Compose comprehensive result
        result = {
            'avg_price': round(avg_price, 2) if avg_price else 0,
            'min_price': round(min_price, 2) if min_price else 0,
            'max_price': round(max_price, 2) if max_price else 0,
            'price_ranges': price_ranges,
            'price_trend': price_trend,
            'city_tier': city_tier,
            'tier_confidence': tier_confidence,
            'market_segment': market_segment,
            'segment_confidence': segment_confidence,
            'price_sources': price_sources,
            'last_updated': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'data_points': len(price_sources),
            'confidence': min(1.0, (tier_confidence + segment_confidence + trend_confidence) / 3),
            'market_analysis': {
                'trend': price_trend,
                'trend_confidence': trend_confidence,
                'city_tier': city_tier,
                'market_segment': market_segment,
                'price_per_sqft': {
                    'market_avg': round(avg_price, 2) if avg_price else 0,
                    'min': round(min_price, 2) if min_price else 0,
                    'max': round(max_price, 2) if max_price else 0
                },
                'analysis_method': price_sources[0]['method'] if price_sources else 'estimation'
            }
        }
        
        return result
        
    except Exception as e:
        logger.error(f"Error in dynamic price analysis for {city}: {str(e)}")
        return {
            'avg_price': 0,
            'min_price': 0,
            'max_price': 0,
            'price_ranges': {},
            'price_trend': 'unknown',
            'city_tier': 'unknown',
            'tier_confidence': 0.0,
            'market_segment': 'unknown',
            'segment_confidence': 0.0,
            'price_sources': [],
            'last_updated': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'data_points': 0,
            'confidence': 0.0,
            'market_analysis': {}
        }

def analyze_price(data, context_text=None, latitude=None, longitude=None, property_data=None):
    """Enhanced price analysis using comprehensive market data and location factors"""
    try:
        # Extract basic property information
        price_str = str(data.get('market_value', '1')).replace('$', '').replace('₹', '').replace(',', '').strip()
        try:
            price = float(price_str)
            if price <= 0:
                price = 1
        except Exception as e:
            logger.warning(f"Invalid price value: {price_str} ({str(e)})")
            price = 1
            
        sq_ft_str = str(data.get('sq_ft', '1')).replace(',', '').strip()
        try:
            sq_ft = float(re.sub(r'[^\d.]', '', sq_ft_str))
            if sq_ft <= 0:
                sq_ft = 1
        except Exception as e:
            logger.warning(f"Invalid sq_ft value: {sq_ft_str} ({str(e)})")
            sq_ft = 1
            
        city = data.get('city', '').strip() or 'Unknown'
        
        # Detect if this is a rental property
        is_rental = data.get('is_rental', False)
        if not is_rental:
            # Check status and description for rental keywords
            status = data.get('status', '').lower()
            description = data.get('description', '').lower()
            is_rental = any(keyword in status for keyword in ['rent', 'lease', 'let', 'hiring']) or \
                       any(keyword in description for keyword in ['rent', 'lease', 'let', 'hiring', 'monthly', 'per month'])
        
        # Calculate price per sq.ft properly
        price_per_sqft = price / sq_ft if sq_ft > 0 else price
        
        # Get market data for comparison
        market_data = get_hyderabad_market_data()
        
        # Adjust market data based on rental vs purchase
        if is_rental:
            # For rental properties, use monthly rental rates
            market_avg = 25  # ₹25/sq ft/month average for Hyderabad rentals
            market_min = 15  # ₹15/sq ft/month minimum
            market_max = 80  # ₹80/sq ft/month maximum
        else:
            # For purchase properties, use purchase rates
            market_avg = market_data.get('avg_price_per_sqft', 8500) if market_data else 8500
            market_min = market_data.get('min_price_per_sqft', 4500) if market_data else 4500
            market_max = market_data.get('max_price_per_sqft', 25000) if market_data else 25000
        
        # Calculate deviation from market average
        if market_avg > 0:
            deviation = ((price_per_sqft - market_avg) / market_avg) * 100
        else:
            deviation = 0
        
        # Determine assessment based on deviation and price reasonableness - Much more lenient
        if is_rental:
            # Rental property pricing logic
            if price_per_sqft < 5:  # Extremely low rental price
                assessment = "suspicious_pricing"
                confidence = 0.3  # Increased from 0.2
            elif price_per_sqft < market_avg * 0.3:  # Very below market rental
                assessment = "below_market"
                confidence = 0.5  # Increased from 0.4
            elif price_per_sqft < market_avg * 0.7:  # Below market rental
                assessment = "below_market"
                confidence = 0.8  # Increased from 0.7
            elif price_per_sqft <= market_avg * 1.5:  # Market rate rental
                assessment = "market_rate"
                confidence = 0.9  # Increased from 0.8
            elif price_per_sqft <= market_avg * 2.0:  # Above market rental
                assessment = "above_market"
                confidence = 0.8  # Increased from 0.7
            else:  # Very above market rental
                assessment = "premium_pricing"
                confidence = 0.6  # Increased from 0.5
        else:
            # Purchase property pricing logic (existing logic)
            if price_per_sqft < 50:  # Extremely low price - increased from 100
                assessment = "suspicious_pricing"
                confidence = 0.2  # Increased from 0.1
            elif price_per_sqft < market_avg * 0.2:  # Very below market - reduced from 0.3
                assessment = "below_market"
                confidence = 0.4  # Increased from 0.3
            elif price_per_sqft < market_avg * 0.6:  # Below market - reduced from 0.7
                assessment = "below_market"
                confidence = 0.7  # Increased from 0.6
            elif price_per_sqft <= market_avg * 1.5:  # Market rate - increased from 1.3
                assessment = "market_rate"
                confidence = 0.9  # Increased from 0.8
            elif price_per_sqft <= market_avg * 2.5:  # Above market - increased from 2.0
                assessment = "above_market"
                confidence = 0.8  # Increased from 0.7
            else:  # Very above market
                assessment = "premium_pricing"
                confidence = 0.6  # Increased from 0.5
        
        # Generate risk indicators - Much more lenient
        risk_indicators = []
        if is_rental:
            if price_per_sqft < 5:  # Increased from 100
                risk_indicators.append("⚠️ Property priced extremely low (suspicious)")
            elif price_per_sqft < market_avg * 0.3:  # Reduced from 0.3
                risk_indicators.append("⚠️ Property priced significantly below market average")
            elif price_per_sqft > market_avg * 2.0:  # Increased from 2.0
                risk_indicators.append("⚠️ Property priced significantly above market average")
        else:
            if price_per_sqft < 50:  # Increased from 100
                risk_indicators.append("⚠️ Property priced extremely low (suspicious)")
            elif price_per_sqft < market_avg * 0.2:  # Reduced from 0.3
                risk_indicators.append("⚠️ Property priced significantly below market average")
            elif price_per_sqft > market_avg * 2.5:  # Increased from 2.0
                risk_indicators.append("⚠️ Property priced significantly above market average")
        
        # Price ranges for the city - Much more lenient
        if is_rental:
            price_ranges = {
                'budget': {
                    'min': market_avg * 0.4,  # Reduced from 0.5
                    'max': market_avg * 0.8,
                    'description': f'Budget rental properties in {city}'
                },
                'mid_range': {
                    'min': market_avg * 0.8,
                    'max': market_avg * 1.4,  # Increased from 1.2
                    'description': f'Mid-range rental properties in {city}'
                },
                'premium': {
                    'min': market_avg * 1.4,  # Reduced from 1.2
                    'max': market_avg * 2.5,  # Increased from 2.0
                    'description': f'Premium rental properties in {city}'
                }
            }
        else:
            price_ranges = {
                'budget': {
                    'min': market_avg * 0.3,  # Reduced from 0.5
                    'max': market_avg * 0.8,
                    'description': f'Budget properties in {city}'
                },
                'mid_range': {
                    'min': market_avg * 0.8,
                    'max': market_avg * 1.4,  # Increased from 1.2
                    'description': f'Mid-range properties in {city}'
                },
                'premium': {
                    'min': market_avg * 1.4,  # Reduced from 1.2
                    'max': market_avg * 2.5,  # Increased from 2.0
                    'description': f'Premium properties in {city}'
                }
            }
        
        # Determine price range
        price_range = "unknown"
        for range_name, range_data in price_ranges.items():
            if range_data['min'] <= price_per_sqft <= range_data['max']:
                price_range = range_name
                break
        
        return {
            'assessment': assessment,
            'confidence': min(1.0, confidence),  # Ensure confidence is capped at 100%
            'price': price,
            'formatted_price': f"₹{price:,.0f}",
            'price_per_sqft': price_per_sqft,
            'formatted_price_per_sqft': f"₹{price_per_sqft:,.2f}",
            'price_range': price_range,
            'location_price_assessment': f"Price analysis: {assessment}",
            'has_price': True,
            'has_sqft': True,
            'is_rental': is_rental,
            'market_trends': {
                'trend': market_data.get('market_trend', 'unknown') if market_data else 'unknown',
                'growth_rate': market_data.get('growth_rate', 0) if market_data else 0,
                'inflation_rate': market_data.get('inflation_rate', 0) if market_data else 0,
                'market_sentiment': market_data.get('market_sentiment', 'stable') if market_data else 'stable',
                'volatility': market_data.get('market_volatility', 0) if market_data else 0
            },
            'price_factors': {
                'market_average': market_avg,
                'deviation_percentage': deviation,
                'price_reasonableness': 'suspicious' if price_per_sqft < (5 if is_rental else 50) else 'reasonable'
            },
            'risk_indicators': risk_indicators,
            'market_average': market_avg,
            'deviation_percentage': deviation,
            'analysis_method': 'enhanced',
            'price_ranges': price_ranges,
            'city_tier': 'metro' if city.lower() in ['hyderabad', 'mumbai', 'delhi', 'bangalore', 'chennai', 'kolkata'] else 'tier2'
        }
            
    except Exception as e:
        logger.error(f"Error in comprehensive price analysis: {str(e)}")
        return {
            'assessment': 'unknown',
            'confidence': 0.0,
            'price': 0,
            'formatted_price': '₹0',
            'price_per_sqft': 0,
            'formatted_price_per_sqft': '₹0',
            'price_range': 'unknown',
            'location_price_assessment': 'unknown',
            'has_price': False,
            'has_sqft': False,
            'is_rental': False,
            'market_trends': {},
            'price_factors': {},
            'risk_indicators': [],
            'analysis_method': 'error'
        }