#!/usr/bin/env python3
"""
Verification script for automatic sample generation in LIMS
This script tests the automatic generation of samples when lab orders are confirmed.
"""

import odoo
import json
from datetime import datetime

def verify_automatic_sample_generation(cr):
    """Verify automatic sample generation functionality"""
    env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
    
    print("\n" + "="*60)
    print("AUTOMATIC SAMPLE GENERATION VERIFICATION")
    print("="*60)
    print(f"Execution time: {datetime.now()}")
    print("="*60 + "\n")
    
    # 1. Check existing lab orders with generated samples
    print("1. EXISTING LAB ORDERS WITH GENERATED SAMPLES:")
    print("-" * 60)
    
    lab_orders = env['sale.order'].search([
        ('is_lab_request', '=', True),
        ('state', '=', 'sale')
    ])
    
    if not lab_orders:
        print("No confirmed lab orders found.")
    else:
        for order in lab_orders:
            print(f"\nOrder: {order.name}")
            print(f"  Patient: {order.partner_id.name}")
            print(f"  Doctor: {order.doctor_id.name if order.doctor_id else 'None'}")
            print(f"  Generated Samples: {len(order.generated_sample_ids)}")
            
            if order.generated_sample_ids:
                for sample in order.generated_sample_ids:
                    print(f"    - {sample.name} | Barcode: {sample.barcode}")
                    print(f"      Type: {sample.sample_type_product_id.name if sample.sample_type_product_id else 'None'}")
                    print(f"      Volume: {sample.volume_ml} ml")
                    print(f"      Analyses: {sample.analysis_names}")
                    print(f"      State: {sample.state}")
    
    # 2. Test sample generation with a new order
    print("\n2. TESTING NEW SAMPLE GENERATION:")
    print("-" * 60)
    
    try:
        # Get test data
        patient = env.ref('lims_management.demo_patient_1', raise_if_not_found=False)
        doctor = env.ref('lims_management.demo_doctor_1', raise_if_not_found=False)
        
        if not patient:
            print("ERROR: Demo patient not found. Cannot proceed with test.")
            return
        
        # Get some analyses with different sample types
        analyses = env['product.template'].search([
            ('is_analysis', '=', True),
            ('required_sample_type_id', '!=', False)
        ], limit=5)
        
        if not analyses:
            print("ERROR: No analyses with sample types found. Cannot proceed with test.")
            return
        
        print(f"Creating test order with {len(analyses)} analyses...")
        
        # Create order lines
        order_lines = []
        for analysis in analyses:
            order_lines.append((0, 0, {
                'product_id': analysis.product_variant_id.id,
                'product_uom_qty': 1
            }))
        
        # Create test order
        test_order = env['sale.order'].create({
            'partner_id': patient.id,
            'doctor_id': doctor.id if doctor else False,
            'is_lab_request': True,
            'order_line': order_lines
        })
        
        print(f"Created order: {test_order.name}")
        print("Confirming order...")
        
        # Confirm order (this should trigger sample generation)
        test_order.action_confirm()
        
        print(f"\nOrder confirmed. Generated samples: {len(test_order.generated_sample_ids)}")
        
        # Check generated samples
        if test_order.generated_sample_ids:
            print("\nGenerated samples details:")
            
            # Group by sample type to verify grouping logic
            sample_types = {}
            for sample in test_order.generated_sample_ids:
                sample_type_name = sample.sample_type_product_id.name if sample.sample_type_product_id else 'Unknown'
                if sample_type_name not in sample_types:
                    sample_types[sample_type_name] = []
                sample_types[sample_type_name].append(sample)
            
            for sample_type, samples in sample_types.items():
                print(f"\n  Sample Type: {sample_type}")
                for sample in samples:
                    print(f"    - {sample.name}")
                    print(f"      Barcode: {sample.barcode}")
                    print(f"      Volume: {sample.volume_ml} ml")
                    print(f"      Analyses: {sample.analysis_names}")
                    print(f"      State: {sample.state}")
        else:
            print("WARNING: No samples were generated!")
        
        # Check for messages/notifications
        print("\nChecking notifications...")
        messages = test_order.message_ids.filtered(lambda m: m.body)
        for msg in messages[:5]:  # Show last 5 messages
            print(f"  - {msg.body[:100]}...")
        
    except Exception as e:
        print(f"ERROR during test: {str(e)}")
        import traceback
        traceback.print_exc()
    
    # 3. Verify barcode uniqueness
    print("\n3. BARCODE UNIQUENESS CHECK:")
    print("-" * 60)
    
    all_samples = env['stock.lot'].search([
        ('is_lab_sample', '=', True),
        ('barcode', '!=', False)
    ])
    
    barcodes = {}
    duplicates = []
    
    for sample in all_samples:
        if sample.barcode in barcodes:
            duplicates.append((sample.barcode, sample.name, barcodes[sample.barcode]))
        else:
            barcodes[sample.barcode] = sample.name
    
    print(f"Total samples with barcodes: {len(all_samples)}")
    print(f"Unique barcodes: {len(barcodes)}")
    print(f"Duplicates found: {len(duplicates)}")
    
    if duplicates:
        print("\nDUPLICATE BARCODES FOUND:")
        for barcode, name1, name2 in duplicates:
            print(f"  Barcode {barcode}: {name1} and {name2}")
    
    # 4. Check analyses without sample types
    print("\n4. ANALYSES WITHOUT SAMPLE TYPES:")
    print("-" * 60)
    
    analyses_without_type = env['product.template'].search([
        ('is_analysis', '=', True),
        ('required_sample_type_id', '=', False)
    ])
    
    print(f"Found {len(analyses_without_type)} analyses without sample types:")
    for analysis in analyses_without_type[:10]:  # Show first 10
        print(f"  - {analysis.name}")
    
    if len(analyses_without_type) > 10:
        print(f"  ... and {len(analyses_without_type) - 10} more")
    
    # 5. Summary
    print("\n" + "="*60)
    print("SUMMARY:")
    print("="*60)
    
    issues = []
    
    if duplicates:
        issues.append(f"{len(duplicates)} duplicate barcodes found")
    
    if analyses_without_type:
        issues.append(f"{len(analyses_without_type)} analyses without sample types")
    
    if issues:
        print("\n⚠️  ISSUES FOUND:")
        for issue in issues:
            print(f"  - {issue}")
    else:
        print("\n✅ All checks passed successfully!")
    
    print("\n" + "="*60)

if __name__ == '__main__':
    db_name = 'lims_demo'
    try:
        registry = odoo.registry(db_name)
        with registry.cursor() as cr:
            verify_automatic_sample_generation(cr)
    except Exception as e:
        print(f"ERROR: {str(e)}")
        print("\nMake sure:")
        print("1. The Odoo instance is running")
        print("2. The database 'lims_demo' exists")
        print("3. The LIMS module is installed")