"""
CSV to JSON Parser - Generate Navigation, Products, and Accessories JSON Files
Based on AI_PARSING_INSTRUCTIONS.md

This script reads data/products.csv and generates:
1. data/navigation.json - Question flow with conditional logic
2. data/products.json - Product catalog
3. data/accessories.json - Accessory options with compatibility rules

Run: python parse_csv_to_json.py
"""

import csv
import json
from collections import defaultdict
from typing import Dict, List, Set, Tuple

def parse_bool(value):
    """Parse TRUE/FALSE string to boolean"""
    if isinstance(value, str):
        return value.strip().upper() == 'TRUE'
    return bool(value)

def clean_string(value):
    """Clean and strip string values"""
    if isinstance(value, str):
        return value.strip()
    return value or ""

class CSVParser:
    def __init__(self, csv_path: str):
        self.csv_path = csv_path
        self.products = []
        self.accessories = []
        self.base_types = set()
        self.door_subtypes = defaultdict(list)  # subtype -> [products]
        self.window_subtypes = defaultdict(list)
        self.material_counts = defaultdict(lambda: {'aluminum': 0, 'vinyl': 0})
        self.color_counts = defaultdict(lambda: defaultdict(int))  # subtype -> {color: count}
        self.color_by_material = defaultdict(lambda: defaultdict(set))  # subtype -> {material: {colors}}
        self.detailed_products = {}  # Load from questions.json
        
    def load_detailed_product_info(self):
        """Load detailed product info from questions.json"""
        try:
            # Load the code mapping
            try:
                with open('data/product_code_mapping.json', 'r', encoding='utf-8') as f:
                    code_mapping = json.load(f)
            except FileNotFoundError:
                code_mapping = {}
            
            with open('data/questions.json', 'r', encoding='utf-8') as f:
                questions_data = json.load(f)
                
            # Extract all product nodes
            for key, value in questions_data.items():
                if key.startswith('prod-') and value.get('type') == 'product':
                    code = value.get('code')
                    if code:
                        detailed_info = {
                            'title': value.get('title'),
                            'detailedDescription': value.get('description'),
                            'features': value.get('features', []),
                            'image': value.get('image'),
                            'url': value.get('url'),
                            'brochure': value.get('brochure'),
                            'measureGuide': value.get('measureGuide')
                        }
                        
                        # Store under the simplified code
                        self.detailed_products[code] = detailed_info
                        
                        # Also store under all mapped codes
                        for csv_code, simple_code in code_mapping.items():
                            if simple_code == code:
                                self.detailed_products[csv_code] = detailed_info
            
            print(f"✓ Loaded {len(self.detailed_products)} detailed product descriptions")
        except FileNotFoundError:
            print("⚠ questions.json not found - skipping detailed product info")
        except Exception as e:
            print(f"⚠ Error loading product details: {e}")
        
    def parse_csv(self):
        """Parse the CSV file and separate products from accessories"""
        print("📖 Reading CSV file...")
        
        with open(self.csv_path, 'r', encoding='utf-8', errors='ignore') as f:
            reader = csv.reader(f)
            
            # Skip first two header rows
            next(reader)  # Row 1: Category headers
            header_row = next(reader)  # Row 2: Column names
            
            row_count = 0
            for row in reader:
                if len(row) < 11:  # Need at least up to column K
                    continue
                
                row_count += 1
                
                # Skip discontinued items
                if parse_bool(row[0]):  # DISCONT column
                    continue
                
                # Extract basic info
                prod_code = clean_string(row[2])  # PROD_CODE
                category = clean_string(row[3])  # CATEGORY
                description = clean_string(row[5])  # DESCRIPTION
                location = clean_string(row[1])  # LOC_CODE
                
                base_type = clean_string(row[6]) if len(row) > 6 else ""  # Base Type (G)
                door_subtype = clean_string(row[7]) if len(row) > 7 else ""  # Sub-type Door (H)
                window_subtype = clean_string(row[8]) if len(row) > 8 else ""  # Sub-type Window (I)
                is_accessory = parse_bool(row[9]) if len(row) > 9 else False  # Accessory Yes (J)
                specific_item = parse_bool(row[10]) if len(row) > 10 else False  # This Item (K)
                
                # Parse materials (L, M)
                materials = []
                if len(row) > 11 and parse_bool(row[11]):
                    materials.append('Aluminum')
                if len(row) > 12 and parse_bool(row[12]):
                    materials.append('Vinyl')
                
                # Parse colors (N through S+)
                colors = []
                color_columns = [
                    (13, 'Black'), (14, 'White'), (15, 'Bronze'),
                    (16, 'Tan'), (17, 'Mill'), (18, 'Sandstone')
                ]
                for col_idx, color_name in color_columns:
                    if len(row) > col_idx and parse_bool(row[col_idx]):
                        colors.append(color_name)
                
                # Build item data
                item_data = {
                    'id': prod_code,
                    'productCode': prod_code,
                    'category': category,
                    'description': description,
                    'discontinued': False,
                    'location': location,
                    'baseType': base_type,
                    'subType': {
                        'door': door_subtype if door_subtype else None,
                        'window': window_subtype if window_subtype else None
                    },
                    'materials': materials,
                    'colors': colors
                }
                
                # Separate accessories from products
                if is_accessory:
                    # Build accessory-specific data
                    accessory = {
                        **item_data,
                        'accessoryCode': prod_code,
                        'compatibilityRules': self._build_compatibility_rules(
                            door_subtype, window_subtype, category, specific_item
                        ),
                        'optionType': self._infer_option_type(description),
                        'metadata': {
                            'specificItemLink': specific_item
                        }
                    }
                    self.accessories.append(accessory)
                else:
                    # Build product-specific data
                    product = {
                        **item_data,
                        'isAccessory': False,
                        'compatibleAccessories': []  # Will be populated later
                    }
                    
                    # Merge detailed info if available
                    if prod_code in self.detailed_products:
                        detailed = self.detailed_products[prod_code]
                        product.update({
                            'title': detailed['title'],
                            'detailedDescription': detailed['detailedDescription'],
                            'features': detailed['features'],
                            'image': detailed['image'],
                            'url': detailed['url'],
                            'brochure': detailed.get('brochure'),
                            'measureGuide': detailed.get('measureGuide')
                        })
                    
                    self.products.append(product)
                    
                    # Track for navigation building
                    if base_type:
                        self.base_types.add(base_type)
                    
                    # Track subtypes per type
                    if door_subtype:
                        self.door_subtypes[door_subtype].append(product)
                    if window_subtype:
                        self.window_subtypes[window_subtype].append(product)
                    
                    # Count materials per subtype
                    subtype_key = door_subtype or window_subtype or "none"
                    if 'Aluminum' in materials:
                        self.material_counts[subtype_key]['aluminum'] += 1
                        # Track colors per material
                        for color in colors:
                            self.color_by_material[subtype_key]['Aluminum'].add(color)
                    if 'Vinyl' in materials:
                        self.material_counts[subtype_key]['vinyl'] += 1
                        # Track colors per material
                        for color in colors:
                            self.color_by_material[subtype_key]['Vinyl'].add(color)
                    
                    # Count colors per subtype (overall)
                    for color in colors:
                        self.color_counts[subtype_key][color] += 1
            
            print(f"✓ Parsed {row_count} rows")
            print(f"✓ Found {len(self.products)} products")
            print(f"✓ Found {len(self.accessories)} accessories")
    
    def _build_compatibility_rules(self, door_subtype, window_subtype, category, specific_item):
        """Build compatibility rules for accessories"""
        rules = {
            'type': 'category',  # Default
            'subTypeDoor': door_subtype if door_subtype else None,
            'subTypeWindow': window_subtype if window_subtype else None,
            'categories': [category] if category else [],
            'specificProducts': [],
            'requiresMatch': {
                'material': True,  # Usually accessories need matching material
                'color': False  # Colors usually don't need to match
            }
        }
        
        # Determine rule type
        if specific_item:
            rules['type'] = 'specific'
        elif door_subtype or window_subtype:
            rules['type'] = 'subType'
        
        return rules
    
    def _infer_option_type(self, description):
        """Infer option type from description"""
        desc_upper = description.upper()
        
        if 'HANDLE' in desc_upper:
            return 'handle'
        elif 'INSERT' in desc_upper or 'GLASS' in desc_upper:
            return 'insert'
        elif 'HARDWARE' in desc_upper:
            return 'hardware'
        elif 'SCREEN' in desc_upper:
            return 'screen'
        else:
            return 'option'
    
    def link_accessories_to_products(self):
        """Link compatible accessories to products"""
        print("🔗 Linking accessories to products...")
        
        linked_count = 0
        for product in self.products:
            compatible = []
            
            for accessory in self.accessories:
                rules = accessory['compatibilityRules']
                
                # Check by subtype
                if rules['type'] == 'subType':
                    prod_door = product['subType']['door']
                    prod_window = product['subType']['window']
                    acc_door = rules['subTypeDoor']
                    acc_window = rules['subTypeWindow']
                    
                    if (prod_door and prod_door == acc_door) or \
                       (prod_window and prod_window == acc_window):
                        # Check material compatibility if required
                        if rules['requiresMatch']['material']:
                            # Check if they share any materials
                            if any(m in product['materials'] for m in accessory['materials']):
                                compatible.append(accessory['id'])
                                linked_count += 1
                        else:
                            compatible.append(accessory['id'])
                            linked_count += 1
                
                # Check by category
                elif rules['type'] == 'category':
                    if product['category'] in rules['categories']:
                        compatible.append(accessory['id'])
                        linked_count += 1
            
            product['compatibleAccessories'] = compatible
        
        print(f"✓ Created {linked_count} product-accessory links")
    
    def build_navigation(self):
        """Build navigation JSON with conditional logic"""
        print("🗺️  Building navigation flow...")
        
        navigation = {}
        
        # Question 1: Base Type Selection
        navigation['start'] = {
            'type': 'question',
            'inputType': 'button',
            'title': 'What are you looking for?',
            'subtitle': 'Select the product category',
            'answers': []
        }
        
        # Add base type options
        sorted_types = sorted(self.base_types)
        for base_type in sorted_types:
            emoji = '🚪' if 'door' in base_type.lower() else '🪟'
            next_key = f'q-{base_type.lower()}-type'
            
            navigation['start']['answers'].append({
                'caption': base_type,
                'image': emoji,
                'next': next_key,
                'filter': {
                    'baseType': base_type
                }
            })
        
        # Question 2: Sub-type Selection for Doors
        if self.door_subtypes:
            door_subtypes = sorted(self.door_subtypes.keys())
            navigation['q-door-type'] = {
                'type': 'question',
                'inputType': 'button',
                'title': 'What type of door?',
                'subtitle': 'Select the door category',
                'answers': []
            }
            
            for subtype in door_subtypes:
                products = self.door_subtypes[subtype]
                
                # Check if material question is needed
                needs_material = self._needs_material_question(subtype)
                
                # Determine next question
                if needs_material:
                    next_key = f'q-material-{subtype.lower().replace(" ", "-")}'
                else:
                    # No material choice needed - determine single material and check colors
                    single_material = 'Aluminum' if self.material_counts[subtype]['aluminum'] > 0 else 'Vinyl'
                    needs_color = self._needs_color_question(subtype, single_material)
                    next_key = f'q-color-{subtype.lower().replace(" ", "-")}-{single_material.lower()}' if needs_color else 'q-dimensions'
                
                # Auto-apply material if only one
                filter_obj = {
                    'baseType': 'Door',
                    'subType': subtype
                }
                
                if not needs_material:
                    # Auto-apply the single material
                    if self.material_counts[subtype]['aluminum'] > 0:
                        filter_obj['material'] = 'Aluminum'
                    elif self.material_counts[subtype]['vinyl'] > 0:
                        filter_obj['material'] = 'Vinyl'
                    
                    # If no color question either, auto-apply single color
                    single_material = filter_obj['material']
                    if not self._needs_color_question(subtype, single_material):
                        colors = list(self.color_by_material[subtype][single_material])
                        if len(colors) == 1:
                            filter_obj['color'] = colors[0]
                
                navigation['q-door-type']['answers'].append({
                    'caption': subtype,
                    'image': '🚪',
                    'next': next_key,
                    'filter': filter_obj
                })
                
                # Create material question if needed
                if needs_material:
                    self._create_material_question(navigation, subtype, 'Door')
                # Create color question if material skipped but color needed
                elif next_key.startswith('q-color-'):
                    single_material = 'Aluminum' if self.material_counts[subtype]['aluminum'] > 0 else 'Vinyl'
                    self._create_color_question(navigation, subtype, single_material, 'Door')
        
        # Question 2: Sub-type Selection for Windows
        if self.window_subtypes:
            window_subtypes = sorted(self.window_subtypes.keys())
            navigation['q-window-type'] = {
                'type': 'question',
                'inputType': 'button',
                'title': 'What type of window?',
                'subtitle': 'Select the window category',
                'answers': []
            }
            
            for subtype in window_subtypes:
                needs_material = self._needs_material_question(subtype)
                
                # Determine next question
                if needs_material:
                    next_key = f'q-material-{subtype.lower().replace(" ", "-")}'
                else:
                    # No material choice needed - determine single material and check colors
                    single_material = 'Aluminum' if self.material_counts[subtype]['aluminum'] > 0 else 'Vinyl'
                    needs_color = self._needs_color_question(subtype, single_material)
                    next_key = f'q-color-{subtype.lower().replace(" ", "-")}-{single_material.lower()}' if needs_color else 'q-dimensions'
                
                filter_obj = {
                    'baseType': 'Window',
                    'subType': subtype
                }
                
                if not needs_material:
                    if self.material_counts[subtype]['aluminum'] > 0:
                        filter_obj['material'] = 'Aluminum'
                    elif self.material_counts[subtype]['vinyl'] > 0:
                        filter_obj['material'] = 'Vinyl'
                    
                    # If no color question either, auto-apply single color
                    single_material = filter_obj['material']
                    if not self._needs_color_question(subtype, single_material):
                        colors = list(self.color_by_material[subtype][single_material])
                        if len(colors) == 1:
                            filter_obj['color'] = colors[0]
                
                navigation['q-window-type']['answers'].append({
                    'caption': subtype,
                    'image': '🪟',
                    'next': next_key,
                    'filter': filter_obj
                })
                
                if needs_material:
                    self._create_material_question(navigation, subtype, 'Window')
                # Create color question if material skipped but color needed
                elif next_key.startswith('q-color-'):
                    single_material = 'Aluminum' if self.material_counts[subtype]['aluminum'] > 0 else 'Vinyl'
                    self._create_color_question(navigation, subtype, single_material, 'Window')
        
        # Final Question: Dimensions
        navigation['q-dimensions'] = {
            'type': 'question',
            'inputType': 'form',
            'title': 'Enter Product Dimensions',
            'subtitle': 'Please provide the measurements',
            'fields': [
                {
                    'name': 'width',
                    'label': 'Width (inches)',
                    'type': 'number',
                    'required': True,
                    'placeholder': 'e.g., 36'
                },
                {
                    'name': 'height',
                    'label': 'Height (inches)',
                    'type': 'number',
                    'required': True,
                    'placeholder': 'e.g., 80'
                }
            ],
            'next': 'results'
        }
        
        print(f"✓ Created {len(navigation)} navigation nodes")
        return navigation
    
    def _needs_material_question(self, subtype):
        """Check if a subtype needs a material selection question"""
        aluminum = self.material_counts[subtype]['aluminum']
        vinyl = self.material_counts[subtype]['vinyl']
        
        # Show material question if both materials exist
        return aluminum > 0 and vinyl > 0
    
    def _create_material_question(self, navigation, subtype, base_type):
        """Create a material selection question"""
        question_key = f'q-material-{subtype.lower().replace(" ", "-")}'
        
        navigation[question_key] = {
            'type': 'question',
            'inputType': 'button',
            'title': 'Select Material',
            'subtitle': f'Choose your preferred material for {subtype}',
            'conditional': {
                'type': 'material',
                'fallbackNext': 'q-dimensions'
            },
            'answers': []
        }
        
        # Add material options
        if self.material_counts[subtype]['aluminum'] > 0:
            # Check if color question needed after aluminum selection
            needs_color = self._needs_color_question(subtype, 'Aluminum')
            next_key_al = f'q-color-{subtype.lower().replace(" ", "-")}-aluminum' if needs_color else 'q-dimensions'
            
            navigation[question_key]['answers'].append({
                'caption': 'Aluminum',
                'image': '🔩',
                'next': next_key_al,
                'filter': {
                    'baseType': base_type,
                    'subType': subtype,
                    'material': 'Aluminum'
                }
            })
        
        if self.material_counts[subtype]['vinyl'] > 0:
            # Check if color question needed after vinyl selection
            needs_color = self._needs_color_question(subtype, 'Vinyl')
            next_key_vin = f'q-color-{subtype.lower().replace(" ", "-")}-vinyl' if needs_color else 'q-dimensions'
            
            navigation[question_key]['answers'].append({
                'caption': 'Vinyl',
                'image': '🪟',
                'next': next_key_vin,
                'filter': {
                    'baseType': base_type,
                    'subType': subtype,
                    'material': 'Vinyl'
                }
            })
        
        # Create color questions for each material option
        if self.material_counts[subtype]['aluminum'] > 0 and self._needs_color_question(subtype, 'Aluminum'):
            self._create_color_question(navigation, subtype, 'Aluminum', base_type)
        if self.material_counts[subtype]['vinyl'] > 0 and self._needs_color_question(subtype, 'Vinyl'):
            self._create_color_question(navigation, subtype, 'Vinyl', base_type)
    
    def _needs_color_question(self, subtype, material):
        """Check if a subtype+material combination needs a color selection question"""
        colors = self.color_by_material[subtype][material]
        # Show color question if multiple colors exist
        return len(colors) > 1
    
    def _create_color_question(self, navigation, subtype, material, base_type):
        """Create a color selection question"""
        question_key = f'q-color-{subtype.lower().replace(" ", "-")}-{material.lower()}'
        
        navigation[question_key] = {
            'type': 'question',
            'inputType': 'button',
            'title': 'Select Color',
            'subtitle': f'Choose your preferred color for {material} {subtype}',
            'conditional': {
                'type': 'color',
                'fallbackNext': 'q-dimensions'
            },
            'answers': []
        }
        
        # Get available colors for this subtype+material
        colors = sorted(self.color_by_material[subtype][material])
        
        # Color emoji mapping
        color_emojis = {
            'Black': '⬛',
            'White': '⬜',
            'Bronze': '🟫',
            'Tan': '🟤',
            'Mill': '⚪',
            'Sandstone': '🟨'
        }
        
        for color in colors:
            navigation[question_key]['answers'].append({
                'caption': color,
                'image': color_emojis.get(color, '🎨'),
                'next': 'q-dimensions',
                'filter': {
                    'baseType': base_type,
                    'subType': subtype,
                    'material': material,
                    'color': color
                }
            })
    
    def save_json_files(self, navigation):
        """Save all three JSON files"""
        print("💾 Saving JSON files...")
        
        # Save products.json
        with open('data/products.json', 'w', encoding='utf-8') as f:
            json.dump(self.products, f, indent=2)
        print(f"✓ Saved data/products.json ({len(self.products)} products)")
        
        # Save accessories.json
        with open('data/accessories.json', 'w', encoding='utf-8') as f:
            json.dump(self.accessories, f, indent=2)
        print(f"✓ Saved data/accessories.json ({len(self.accessories)} accessories)")
        
        # Save navigation.json
        with open('data/navigation.json', 'w', encoding='utf-8') as f:
            json.dump(navigation, f, indent=2)
        print(f"✓ Saved data/navigation.json ({len(navigation)} nodes)")
    
    def print_statistics(self):
        """Print parsing statistics"""
        print("\n" + "="*60)
        print("PARSING STATISTICS")
        print("="*60)
        print(f"Total Products: {len(self.products)}")
        print(f"Total Accessories: {len(self.accessories)}")
        print(f"Base Types: {', '.join(sorted(self.base_types))}")
        print(f"Door Subtypes: {len(self.door_subtypes)}")
        print(f"Window Subtypes: {len(self.window_subtypes)}")
        print()
        print("Material Distribution:")
        for subtype, counts in sorted(self.material_counts.items()):
            if counts['aluminum'] > 0 or counts['vinyl'] > 0:
                needs_q = "✓ Material Q" if (counts['aluminum'] > 0 and counts['vinyl'] > 0) else "✗ Skip"
                print(f"  {subtype:20} - Al:{counts['aluminum']:3} Vinyl:{counts['vinyl']:3} [{needs_q}]")
        print("="*60)

def main():
    csv_path = 'data/products.csv'
    
    print("🚀 CSV to JSON Parser")
    print("="*60)
    
    try:
        parser = CSVParser(csv_path)
        parser.load_detailed_product_info()
        parser.parse_csv()
        parser.link_accessories_to_products()
        navigation = parser.build_navigation()
        parser.save_json_files(navigation)
        parser.print_statistics()
        
        print("\n✅ All JSON files generated successfully!")
        print("\nNext steps:")
        print("1. Review data/navigation.json for question flow")
        print("2. Review data/products.json for product data")
        print("3. Review data/accessories.json for accessory compatibility")
        print("4. Test the application in your browser")
        
    except FileNotFoundError:
        print(f"❌ Error: Could not find {csv_path}")
        print("   Make sure products.csv exists in the data/ folder")
    except Exception as e:
        print(f"❌ Error: {e}")
        import traceback
        traceback.print_exc()

if __name__ == '__main__':
    main()
