"""
Generate Bitwise Helper File for Product Classification
Creates a helper file with bitwise flags based on product attributes (columns G-S)
"""

import csv
import json
from collections import defaultdict

# Bit position definitions
BIT_DEFINITIONS = {
    # Base Type (Bits 0-1)
    'base_door': 0,          # 2^0 = 1
    'base_window': 1,        # 2^1 = 2
    
    # Product Flags (Bits 2-3)
    'is_accessory': 2,       # 2^2 = 4
    'specific_item': 3,      # 2^3 = 8
    
    # Materials (Bits 4-5)
    'material_aluminum': 4,   # 2^4 = 16
    'material_vinyl': 5,      # 2^5 = 32
    
    # Colors (Bits 6-11)
    'color_black': 6,         # 2^6 = 64
    'color_white': 7,         # 2^7 = 128
    'color_bronze': 8,        # 2^8 = 256
    'color_tan': 9,           # 2^9 = 512
    'color_mill': 10,         # 2^10 = 1024
    'color_sandstone': 11,    # 2^11 = 2048
}

# Sub-type bits will be assigned dynamically (starting at bit 12)
SUBTYPE_BIT_START = 12

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

def calculate_bit_value(row, subtype_map):
    """Calculate the bitwise value for a product row"""
    bit_value = 0
    explanation = []
    
    # Base Type (Column G - index 6)
    base_type = row[6].strip() if len(row) > 6 and row[6] else ""
    if base_type.lower() == 'door':
        bit_value |= (1 << BIT_DEFINITIONS['base_door'])
        explanation.append('Door')
    elif base_type.lower() == 'window':
        bit_value |= (1 << BIT_DEFINITIONS['base_window'])
        explanation.append('Window')
    
    # Accessory Flag (Column J - index 9)
    if len(row) > 9 and parse_bool(row[9]):
        bit_value |= (1 << BIT_DEFINITIONS['is_accessory'])
        explanation.append('Accessory')
    
    # Specific Item Link (Column K - index 10)
    if len(row) > 10 and parse_bool(row[10]):
        bit_value |= (1 << BIT_DEFINITIONS['specific_item'])
        explanation.append('SpecificItem')
    
    # Materials
    if len(row) > 11 and parse_bool(row[11]):  # Aluminum (Column L)
        bit_value |= (1 << BIT_DEFINITIONS['material_aluminum'])
        explanation.append('Aluminum')
    
    if len(row) > 12 and parse_bool(row[12]):  # Vinyl (Column M)
        bit_value |= (1 << BIT_DEFINITIONS['material_vinyl'])
        explanation.append('Vinyl')
    
    # Colors
    color_columns = [
        (13, 'color_black', 'Black'),
        (14, 'color_white', 'White'),
        (15, 'color_bronze', 'Bronze'),
        (16, 'color_tan', 'Tan'),
        (17, 'color_mill', 'Mill'),
        (18, 'color_sandstone', 'Sandstone'),
    ]
    
    for col_idx, bit_key, color_name in color_columns:
        if len(row) > col_idx and parse_bool(row[col_idx]):
            bit_value |= (1 << BIT_DEFINITIONS[bit_key])
            explanation.append(color_name)
    
    # Sub-types (Columns H and I - indices 7 and 8)
    door_subtype = row[7].strip() if len(row) > 7 and row[7] else ""
    window_subtype = row[8].strip() if len(row) > 8 and row[8] else ""
    
    if door_subtype and door_subtype in subtype_map:
        bit_pos = subtype_map[door_subtype]
        bit_value |= (1 << bit_pos)
        explanation.append(f'Subtype:{door_subtype}')
    
    if window_subtype and window_subtype in subtype_map:
        bit_pos = subtype_map[window_subtype]
        bit_value |= (1 << bit_pos)
        explanation.append(f'Subtype:{window_subtype}')
    
    return bit_value, explanation

def collect_subtypes(csv_path):
    """Collect all unique sub-types from the CSV"""
    subtypes = set()
    
    with open(csv_path, 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        next(reader)  # Skip first header row
        next(reader)  # Skip second header row
        
        for row in reader:
            if len(row) < 8:
                continue
            
            # Skip discontinued items
            if len(row) > 0 and parse_bool(row[0]):
                continue
            
            # Collect door subtype (column H - index 7)
            if len(row) > 7 and row[7].strip():
                subtypes.add(row[7].strip())
            
            # Collect window subtype (column I - index 8)
            if len(row) > 8 and row[8].strip():
                subtypes.add(row[8].strip())
    
    return sorted(subtypes)

def generate_helper_files(csv_path):
    """Generate helper CSV and JSON files with bitwise values"""
    
    print("Analyzing product data...")
    
    # First pass: collect all unique sub-types
    subtypes = collect_subtypes(csv_path)
    
    # Create subtype bit mapping
    subtype_map = {}
    for idx, subtype in enumerate(subtypes):
        subtype_map[subtype] = SUBTYPE_BIT_START + idx
    
    print(f"Found {len(subtypes)} unique sub-types")
    
    # Second pass: calculate bit values
    results = []
    
    with open(csv_path, 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        next(reader)  # Skip first header row
        next(reader)  # Skip second header row
        
        for row in reader:
            if len(row) < 3:
                continue
            
            prod_code = row[2].strip()  # Column C - PROD_CODE
            discontinued = parse_bool(row[0])  # Column A - DISCONT
            
            bit_value, explanation = calculate_bit_value(row, subtype_map)
            
            results.append({
                'PROD_CODE': prod_code,
                'BIT_VALUE': bit_value,
                'BIT_HEX': f"0x{bit_value:X}",
                'BIT_BINARY': f"{bit_value:b}",
                'DISCONTINUED': discontinued,
                'FLAGS': ' | '.join(explanation) if explanation else 'None'
            })
    
    # Filter out discontinued products for output files
    active_results = [r for r in results if not r['DISCONTINUED']]
    
    print(f"Total products processed: {len(results)}")
    print(f"Active products: {len(active_results)}")
    print(f"Discontinued products (filtered out): {len(results) - len(active_results)}")
    
    # Write CSV helper file (only active products)
    csv_output = 'data/product_bitwise.csv'
    with open(csv_output, 'w', newline='', encoding='utf-8') as f:
        writer = csv.DictWriter(f, fieldnames=['PROD_CODE', 'BIT_VALUE', 'BIT_HEX', 'BIT_BINARY', 'DISCONTINUED', 'FLAGS'])
        writer.writeheader()
        writer.writerows(active_results)
    
    print(f"✓ Created {csv_output}")
    
    # Write JSON helper file (only active products)
    json_output = 'data/product_bitwise.json'
    with open(json_output, 'w', encoding='utf-8') as f:
        json.dump(active_results, f, indent=2)
    
    print(f"✓ Created {json_output}")
    
    # Create bit legend/documentation
    legend = {
        'description': 'Bitwise flag system for product classification',
        'bit_definitions': {
            'base_attributes': {
                'bit_0 (1)': 'Base Type = Door',
                'bit_1 (2)': 'Base Type = Window',
                'bit_2 (4)': 'Is Accessory',
                'bit_3 (8)': 'Specific Item Link',
            },
            'materials': {
                'bit_4 (16)': 'Material = Aluminum',
                'bit_5 (32)': 'Material = Vinyl',
            },
            'colors': {
                'bit_6 (64)': 'Color = Black',
                'bit_7 (128)': 'Color = White',
                'bit_8 (256)': 'Color = Bronze',
                'bit_9 (512)': 'Color = Tan',
                'bit_10 (1024)': 'Color = Mill',
                'bit_11 (2048)': 'Color = Sandstone',
            },
            'subtypes': {}
        },
        'usage_examples': {
            'check_if_door': 'bit_value & 1',
            'check_if_window': 'bit_value & 2',
            'check_if_aluminum': 'bit_value & 16',
            'check_if_white': 'bit_value & 128',
            'check_multiple': '(bit_value & 1) and (bit_value & 16)  # Door AND Aluminum',
        }
    }
    
    # Add subtype mappings to legend
    for subtype, bit_pos in sorted(subtype_map.items(), key=lambda x: x[1]):
        bit_value = 1 << bit_pos
        legend['bit_definitions']['subtypes'][f'bit_{bit_pos} ({bit_value})'] = f'Subtype = {subtype}'
        legend['usage_examples'][f'check_subtype_{subtype.replace(" ", "_").lower()}'] = f'bit_value & {bit_value}'
    
    # Write legend file
    legend_output = 'data/bitwise_legend.json'
    with open(legend_output, 'w', encoding='utf-8') as f:
        json.dump(legend, f, indent=2)
    
    print(f"✓ Created {legend_output}")
    
    # Generate statistics
    stats = {
        'total_products': len([r for r in results if not r['DISCONTINUED']]),
        'total_discontinued': len([r for r in results if r['DISCONTINUED']]),
        'total_accessories': len([r for r in results if not r['DISCONTINUED'] and (r['BIT_VALUE'] & 4)]),
        'doors': len([r for r in results if not r['DISCONTINUED'] and (r['BIT_VALUE'] & 1)]),
        'windows': len([r for r in results if not r['DISCONTINUED'] and (r['BIT_VALUE'] & 2)]),
        'aluminum_products': len([r for r in results if not r['DISCONTINUED'] and (r['BIT_VALUE'] & 16)]),
        'vinyl_products': len([r for r in results if not r['DISCONTINUED'] and (r['BIT_VALUE'] & 32)]),
        'multi_material': len([r for r in results if not r['DISCONTINUED'] and (r['BIT_VALUE'] & 16) and (r['BIT_VALUE'] & 32)]),
    }
    
    print("\n" + "="*60)
    print("STATISTICS")
    print("="*60)
    print(f"Total Active Products: {stats['total_products']}")
    print(f"Total Discontinued: {stats['total_discontinued']}")
    print(f"Accessories: {stats['total_accessories']}")
    print(f"Doors: {stats['doors']}")
    print(f"Windows: {stats['windows']}")
    print(f"Aluminum Products: {stats['aluminum_products']}")
    print(f"Vinyl Products: {stats['vinyl_products']}")
    print(f"Multi-Material Products: {stats['multi_material']}")
    print(f"Unique Sub-types: {len(subtypes)}")
    print("="*60)
    
    # Show example products
    print("\nEXAMPLE PRODUCTS:")
    print("-"*60)
    for i, result in enumerate(active_results[:5]):
        print(f"{result['PROD_CODE']:12} | {result['BIT_VALUE']:6} | {result['BIT_HEX']:8} | {result['FLAGS']}")
    print("-"*60)
    
    return active_results, legend, subtype_map

if __name__ == '__main__':
    csv_path = 'data/products.csv'
    
    try:
        results, legend, subtype_map = generate_helper_files(csv_path)
        print("\n✓ All helper files generated successfully!")
        print("\nGenerated files:")
        print("  - data/product_bitwise.csv   (CSV format with bit values)")
        print("  - data/product_bitwise.json  (JSON format with bit values)")
        print("  - data/bitwise_legend.json   (Bit mapping documentation)")
        
    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()
