"""
Improved Rule-Based Case Data Extractor
Phase 5 - Better Regex Patterns for NY Legal Documents
"""

import re
import json
from datetime import datetime

class SimpleCaseExtractor:
    """Extract case information using improved regex patterns"""
    
    def __init__(self):
        # Specific patterns for NY Supreme Court documents
        self.patterns = {
            'index_number': [
                r'Index\s*No\.?\s*:?\s*(\d{4,}[\/\-]\d{4,}[A-Z]*)',
                r'Index\s*No\.?\s*(\d{4,}[\/\-]\d{4,}[A-Z]*)',
                r'Index\s*(?:No|Number)[.:\s]*(\d+\/\d+[A-Z]*)',
                r'SUPREME\s*COURT.*?Index\s*No[.:\s]*(\S+)',
            ],
            'defendant_name': [
                # Pattern: "-against-" ke baad wali line
                r'-against-\s*\n\s*([A-Z][A-Za-z\s,\.\'-]+?)(?:\n|,|Index|Plaintiff)',
                # Pattern: "Defendant:" label ke baad
                r'Defendants?\s*:?\s*\n?\s*([A-Z][A-Za-z\s,\.\'-]{3,50}?)(?:\n|,|resid|Index|Plaintiff)',
                # Pattern: against keyword ke baad
                r'against\s+([A-Z][A-Za-z\s,\.\'-]{3,50}?)(?:\n|,|resid)',
            ],
            'plaintiff_name': [
                # Pattern: First name before "-against-"
                r'([A-Z][A-Za-z\s,\.\'-]+?)\s*\n\s*-against-',
                # Pattern: "Plaintiff" label ke pehle ya baad
                r'([A-Z][A-Za-z\s,\.\'-]{3,50}?)\s*,?\s*Plaintiff',
                r'Plaintiff\s*:?\s*([A-Z][A-Za-z\s,\.\'-]{3,50}?)(?:\n|,|against)',
            ],
            'amount_sued': [
                r'amount\s*(?:of|sued|claimed|demanded|sought)?\s*:?\s*\$?\s*([\d,]+\.?\d{0,2})',
                r'sum\s*(?:of|sued)?\s*:?\s*\$?\s*([\d,]+\.?\d{0,2})',
                r'\$\s*([\d,]+\.?\d{2})',
                r'judgment\s*(?:amount|sum)?\s*(?:of|in)?\s*\$?\s*([\d,]+\.?\d{0,2})',
            ],
            'county': [
                r'COUNTY\s+OF\s+([A-Z]+)',
                r'County\s*(?:of|:)\s*([A-Z][A-Za-z\s]+?)(?:\n|\))',
                r'in the County of\s+([A-Z]+)',
            ],
            'case_type': [
                r'(CONSUMER\s*CREDIT\s*TRANSACTION)',
                r'Case\s*Type\s*:?\s*([A-Za-z\s]+?)(?:\n|Court|Index)',
                r'(?:Consumer\s*Credit|Commercial|Contract|Tort|Foreclosure|Eviction)',
            ],
            'filing_date': [
                r'(?:Dated|Filed|Date)[:\s]*([A-Z][a-z]+\s+\d{1,2},?\s*\d{4})',
                r'(\d{1,2}/\d{1,2}/\d{4})',
                r'(\d{4}-\d{2}-\d{2})',
            ],
            'plaintiff_attorney': [
                r'Attorney\s*(?:s\s*)?(?:for|of)\s*(?:Plaintiff|Petitioner)[:\s]*([A-Za-z\s,\.\'\-&]+?)(?:\n|,|Esq|P\.?C\.?|LLP|LLC)',
                r'([A-Z][A-Za-z\s,\.\'\-&]+?(?:Esq|P\.?C\.?|LLP|LLC|P\.?A\.?))',
            ],
            'defendant_address': [
                r'(?:residing at|residence|address|located at)\s*(?:is|:)?\s*([\d]+[A-Za-z\s,\.\'-]+?(?:Street|Avenue|Road|Drive|Blvd|Lane|Way|Court|Plaza|Suite|Apt)[^,\n]*)',
                r'Defendant[^.]*?(?:residing at|address)[^.]*?([\d]+[A-Za-z\s,\.\'-]+)',
            ],
        }
    
    def extract(self, full_text, pages):
        """Extract all fields from document text"""
        result = {}
        
        # Clean text first
        clean_text = self._clean_text(full_text)
        
        for field, pattern_list in self.patterns.items():
            value = None
            evidence = None
            page_num = None
            
            for pattern in pattern_list:
                try:
                    match = re.search(pattern, clean_text, re.IGNORECASE | re.MULTILINE)
                    if match and match.groups():
                        raw_value = match.group(1).strip()
                        # Clean up value
                        value = self._clean_value(raw_value, field)
                        
                        if value and len(value) > 2:
                            page_num = self._find_page_number(match.group(0), pages)
                            evidence = match.group(0).strip()[:200]
                            break
                except Exception as e:
                    continue
            
            result[field] = {
                'value': value,
                'page': page_num,
                'evidence': evidence,
                'confidence': 0.7 if value else 0
            }
        
        # Post-process defendant name (remove common false matches)
        result = self._post_process_defendant(result, clean_text)
        result = self._post_process_plaintiff(result, clean_text)
        result = self._post_process_attorney(result, clean_text)
        
        # Extract city, state, zip from address
        result = self._extract_address_parts(result)
        
        # Add summary
        result['ai_summary'] = {
            'value': self._generate_summary(result, clean_text),
            'page': 1,
            'evidence': 'Generated from document text',
            'confidence': 0.6
        }
        
        # Case status
        result['current_case_status'] = {
            'value': self._determine_status(clean_text),
            'page': None,
            'evidence': 'Determined from document content',
            'confidence': 0.4
        }
        
        # Court documents
        result['court_document_names'] = {
            'value': self._extract_document_names(clean_text),
            'page': 1,
            'evidence': 'Extracted from document headers',
            'confidence': 0.6
        }
        
        # NYSCEF link
        result['nyscef_link'] = {
            'value': self._extract_nyscef(clean_text),
            'page': None,
            'evidence': None,
            'confidence': 0.8 if self._extract_nyscef(clean_text) else 0
        }
        
        return result
    
    def _clean_text(self, text):
        """Clean and normalize text"""
        # Replace multiple newlines
        text = re.sub(r'\n\s*\n\s*\n+', '\n\n', text)
        # Remove excessive spaces
        text = re.sub(r'[ \t]+', ' ', text)
        return text
    
    def _clean_value(self, value, field_type):
        """Clean extracted value based on field type"""
        if not value:
            return None
        
        value = value.strip()
        
        # Remove common artifacts
        remove_words = [
            'residence is in the County of',
            'is an active foreign entity',
            'conducting business',
            'Subsequently',
            'thereafter',
            'hereinafter',
        ]
        
        for word in remove_words:
            if value.lower().startswith(word.lower()):
                return None
        
        # Field-specific cleaning
        if field_type == 'defendant_name':
            # Should be a person or company name
            if len(value) < 3 or len(value) > 100:
                return None
            if any(word in value.lower() for word in ['county', 'residence', 'court', 'index']):
                return None
        
        if field_type == 'plaintiff_name':
            if len(value) < 2 or len(value) > 100:
                return None
            if any(word in value.lower() for word in ['county', 'court', 'index', 'summons']):
                return None
        
        if field_type == 'plaintiff_attorney':
            if len(value) < 3:
                return None
            if value.lower() in ['subsequently', 'thereafter', 'hereinafter']:
                return None
        
        return value.strip(' ,.')
    
    def _post_process_defendant(self, result, text):
        """Improve defendant name extraction"""
        defendant = result.get('defendant_name', {})
        
        if not defendant.get('value'):
            # Try to find defendant after "-against-"
            match = re.search(r'-against-\s*\n\s*([A-Z][A-Za-z\s,\.\'-]+?)(?:\n|,|resid|Index|Plaintiff)', text, re.IGNORECASE)
            if match:
                value = match.group(1).strip()
                if len(value) > 2 and len(value) < 80:
                    defendant['value'] = value
                    defendant['evidence'] = match.group(0).strip()[:200]
                    defendant['confidence'] = 0.7
        
        result['defendant_name'] = defendant
        return result
    
    def _post_process_plaintiff(self, result, text):
        """Improve plaintiff name extraction"""
        plaintiff = result.get('plaintiff_name', {})
        
        if not plaintiff.get('value') or len(plaintiff.get('value', '')) > 80:
            # Try to find plaintiff before "-against-"
            match = re.search(r'([A-Z][A-Za-z\s,\.\'\-]+?(?:LLC|Inc|Corp|Corporation|Company|Bank|Association|Trust|LP))\s*\n\s*-against-', text, re.IGNORECASE)
            if match:
                value = match.group(1).strip()
                plaintiff['value'] = value
                plaintiff['evidence'] = match.group(0).strip()[:200]
                plaintiff['confidence'] = 0.7
            else:
                # Try simpler pattern
                match = re.search(r'([A-Z][A-Za-z\s,\.\'\-]{3,40}?)\s*\n\s*-against-', text)
                if match:
                    value = match.group(1).strip()
                    if not any(w in value.lower() for w in ['supreme', 'court', 'county', 'state']):
                        plaintiff['value'] = value
                        plaintiff['evidence'] = match.group(0).strip()[:200]
                        plaintiff['confidence'] = 0.6
        
        result['plaintiff_name'] = plaintiff
        return result
    
    def _post_process_attorney(self, result, text):
        """Improve attorney extraction"""
        attorney = result.get('plaintiff_attorney', {})
        
        if not attorney.get('value') or attorney.get('value') in ['Subsequently', 'thereafter']:
            # Look for law firm pattern
            match = re.search(r'([A-Z][A-Za-z\s,\.\'\-&]+?\s*(?:LLP|LLC|P\.?C\.?|P\.?A\.?|Esq))', text)
            if match:
                attorney['value'] = match.group(1).strip()
                attorney['confidence'] = 0.6
            else:
                attorney['value'] = None
                attorney['confidence'] = 0
        
        result['plaintiff_attorney'] = attorney
        return result
    
    def _extract_address_parts(self, result):
        """Extract city, state, zip from address or text"""
        address = result.get('defendant_address', {}).get('value', '')
        full_text = result.get('defendant_address', {}).get('evidence', '')
        
        city = None
        state = None
        zip_code = None
        
        # Try from address first
        if address:
            # Pattern: City, State ZIP
            match = re.search(r'([A-Z][A-Za-z\s]+),\s*([A-Z]{2})\s*(\d{5}(?:-\d{4})?)', address)
            if match:
                city = match.group(1).strip()
                state = match.group(2).strip()
                zip_code = match.group(3).strip()
        
        # If not found, search full text
        if not city:
            match = re.search(r'(?:City of|in)\s+([A-Z][A-Za-z\s]+),\s*(?:New\s*York|NY)', full_text, re.IGNORECASE)
            if match:
                city = match.group(1).strip()
        
        if not state:
            if re.search(r'New\s*York|NY', full_text, re.IGNORECASE):
                state = 'NY'
        
        if not zip_code:
            match = re.search(r'(?:NY|New York)\s*(\d{5})', full_text)
            if match:
                zip_code = match.group(1)
        
        result['city'] = {'value': city, 'page': None, 'evidence': None, 'confidence': 0.5 if city else 0}
        result['state'] = {'value': state, 'page': None, 'evidence': None, 'confidence': 0.6 if state else 0}
        result['zip_code'] = {'value': zip_code, 'page': None, 'evidence': None, 'confidence': 0.5 if zip_code else 0}
        
        return result
    
    def _determine_status(self, text):
        """Determine case status from document content"""
        text_lower = text.lower()
        
        if 'judgment' in text_lower and 'entered' in text_lower:
            return 'Judgment entered'
        elif 'settled' in text_lower or 'settlement' in text_lower:
            return 'Settled'
        elif 'dismissed' in text_lower:
            return 'Dismissed'
        elif 'answer' in text_lower and 'filed' in text_lower:
            return 'Answer filed'
        elif 'summons' in text_lower and 'complaint' in text_lower:
            return 'Summons and complaint filed'
        else:
            return 'Unknown / requires review'
    
    def _extract_document_names(self, text):
        """Extract document type names"""
        doc_types = [
            'Summons', 'Complaint', 'Affidavit', 'Judgment', 
            'Motion', 'Notice', 'Answer', 'Reply', 'Order',
            'Stipulation', 'Subpoena', 'Warrant', 'Petition',
            'Verification', 'Exhibit', 'Memorandum'
        ]
        found = []
        
        text_lower = text.lower()
        for doc in doc_types:
            if doc.lower() in text_lower:
                found.append(doc)
        
        return ', '.join(found) if found else 'Unknown'
    
    def _extract_nyscef(self, text):
        """Extract NYSCEF link if present"""
        match = re.search(r'(https?://[^\s]*nyscef[^\s]*)', text, re.IGNORECASE)
        if match:
            return match.group(1)
        
        match = re.search(r'(https?://iapps\.courts\.state\.ny\.us[^\s]*)', text, re.IGNORECASE)
        if match:
            return match.group(1)
        
        return None
    
    def _find_page_number(self, text, pages):
        """Find which page contains the given text"""
        if not text or not pages:
            return None
        
        search_text = text[:100].strip()
        
        for page in pages:
            if search_text in page.get('text', ''):
                return page['page']
        
        return None
    
    def _generate_summary(self, extracted, text):
        """Generate improved summary"""
        parts = []
        
        plaintiff = extracted.get('plaintiff_name', {}).get('value')
        defendant = extracted.get('defendant_name', {}).get('value')
        amount = extracted.get('amount_sued', {}).get('value')
        case_type = extracted.get('case_type', {}).get('value')
        county = extracted.get('county', {}).get('value')
        index_num = extracted.get('index_number', {}).get('value')
        filing_date = extracted.get('filing_date', {}).get('value')
        
        if plaintiff:
            parts.append(f"{plaintiff} filed a case")
        if defendant:
            parts.append(f"against {defendant}")
        if county:
            parts.append(f"in {county} County")
        if case_type:
            parts.append(f"for {case_type}")
        if amount:
            parts.append(f"seeking ${amount}")
        if index_num:
            parts.append(f"(Index: {index_num})")
        if filing_date:
            parts.append(f"filed on {filing_date}")
        
        if parts:
            return ' '.join(parts) + '.'
        
        return 'Legal document requiring manual review.'