#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script para crear órdenes de laboratorio con resultados validados para probar el reporte PDF
"""

import odoo
import logging
from datetime import datetime, timedelta
import random
from odoo import fields

_logger = logging.getLogger(__name__)


def create_validated_lab_order(env):
    """Crear una orden de laboratorio con resultados completos y validados"""
    
    # Obtener o crear paciente y doctor demo
    patient = env['res.partner'].search([('is_patient', '=', True)], limit=1)
    if not patient:
        patient = env['res.partner'].create({
            'name': 'Juan Pérez (Demo)',
            'is_patient': True,
            'birthdate_date': '1980-05-15',
            'gender': 'male',
            'vat': '12345678',
        })
    
    doctor = env['res.partner'].search([('is_doctor', '=', True)], limit=1)
    if not doctor:
        doctor = env['res.partner'].create({
            'name': 'Dr. María García (Demo)',
            'is_doctor': True,
        })
    
    # Usar usuario admin como técnico y validador
    admin_user = env.ref('base.user_admin')
    technician = admin_user
    validator = admin_user
    
    # Obtener análisis disponibles
    hemograma = env.ref('lims_management.analysis_hemograma')
    glucosa = env.ref('lims_management.analysis_glucosa')
    perfil_lipidico = env.ref('lims_management.analysis_perfil_lipidico')
    
    # Crear orden de laboratorio
    order = env['sale.order'].create({
        'partner_id': patient.id,
        'doctor_id': doctor.id,
        'is_lab_request': True,
        'lab_notes': 'Paciente en ayunas de 12 horas. Control de rutina anual.',
        'order_line': [
            (0, 0, {
                'product_id': hemograma.product_variant_id.id,
                'product_uom_qty': 1,
                'price_unit': hemograma.list_price,
            }),
            (0, 0, {
                'product_id': glucosa.product_variant_id.id,
                'product_uom_qty': 1,
                'price_unit': glucosa.list_price,
            }),
            (0, 0, {
                'product_id': perfil_lipidico.product_variant_id.id,
                'product_uom_qty': 1,
                'price_unit': perfil_lipidico.list_price,
            }),
        ]
    })
    
    # Confirmar orden (genera muestras y pruebas automáticamente)
    order.action_confirm()
    
    _logger.info(f"Orden creada: {order.name}")
    
    # Primero, marcar todas las muestras como recolectadas
    for sample in order.generated_sample_ids:
        sample.write({'state': 'collected'})
    
    # Procesar cada prueba
    for test in order.lab_test_ids:
        # Asignar técnico
        test.write({
            'technician_id': technician.id
        })
        
        # Generar resultados si no existen
        if not test.result_ids:
            # Usar sudo para evitar restricciones de permisos y llamar método interno
            test.sudo()._generate_test_results()
            _logger.info(f"Generados {len(test.result_ids)} resultados para prueba {test.name}")
        
        # Cambiar estado a in_process
        test.write({'state': 'in_process'})
        
        # Ingresar resultados según el tipo de análisis
        for result in test.result_ids:
            parameter = result.parameter_id
            vals = {}
            
            # Solo procesar parámetros numéricos
            if parameter.value_type == 'numeric':
                # Generar valores basados en el parámetro
                if parameter.code == 'HGB':  # Hemoglobina
                    vals['value_numeric'] = random.uniform(11.0, 16.5)  # Algunos fuera de rango
                elif parameter.code == 'HCT':  # Hematocrito
                    vals['value_numeric'] = random.uniform(35.0, 48.0)
                elif parameter.code == 'WBC':  # Leucocitos
                    vals['value_numeric'] = random.uniform(3.5, 11.0)  # Algunos fuera de rango
                elif parameter.code == 'PLT':  # Plaquetas
                    vals['value_numeric'] = random.uniform(140, 450)
                elif parameter.code == 'RBC':  # Eritrocitos
                    vals['value_numeric'] = random.uniform(3.8, 5.8)
                elif parameter.code == 'GLU':  # Glucosa
                    vals['value_numeric'] = random.uniform(65, 125)  # Algunos elevados
                elif parameter.code == 'CHOL':  # Colesterol
                    vals['value_numeric'] = random.uniform(150, 240)  # Algunos elevados
                elif parameter.code == 'TRIG':  # Triglicéridos
                    vals['value_numeric'] = random.uniform(40, 200)  # Algunos elevados
                elif parameter.code == 'HDL':  # HDL
                    vals['value_numeric'] = random.uniform(35, 65)
                elif parameter.code == 'LDL':  # LDL
                    vals['value_numeric'] = random.uniform(70, 160)
                else:
                    # Valor genérico para otros parámetros numéricos
                    if result.applicable_range_id:
                        # Generar valor cercano al rango normal
                        min_val = result.applicable_range_id.normal_min or 0
                        max_val = result.applicable_range_id.normal_max or 100
                        vals['value_numeric'] = random.uniform(min_val * 0.8, max_val * 1.2)
                    else:
                        # Valor por defecto si no hay rango
                        vals['value_numeric'] = random.uniform(1, 100)
                        
                _logger.info(f"Asignando valor numérico {vals.get('value_numeric', 0):.2f} a {parameter.name} ({parameter.code})")
            elif parameter.value_type == 'text':
                vals['value_text'] = "Normal"
            elif parameter.value_type == 'selection':
                vals['value_selection'] = "normal"
            elif parameter.value_type == 'boolean':
                vals['value_boolean'] = False
                
            # Escribir valores
            if vals:
                result.write(vals)
            
            # Agregar notas si está fuera de rango
            if result.is_out_of_range:
                if result.is_critical:
                    result.notes = "Valor crítico. Se recomienda repetir el análisis y consultar con el médico de inmediato."
                else:
                    result.notes = "Valor ligeramente alterado. Se sugiere control en 3 meses."
        
        # Marcar resultados como ingresados
        test.write({'state': 'result_entered'})
        
        # Agregar comentarios a algunas pruebas
        if test.product_id == hemograma:
            test.notes = "Serie roja dentro de parámetros normales. Serie blanca con ligera leucocitosis."
        elif test.product_id == perfil_lipidico:
            test.notes = "Se recomienda dieta baja en grasas y control en 3 meses."
    
    # Validar todas las pruebas
    for test in order.lab_test_ids:
        test.write({
            'state': 'validated',
            'validator_id': validator.id,
            'validation_date': fields.Datetime.now()
        })
    
    _logger.info(f"Todas las pruebas validadas para orden {order.name}")
    
    return order


def create_multiple_test_orders(env, count=3):
    """Crear múltiples órdenes con diferentes escenarios"""
    orders = env['sale.order']
    
    for i in range(count):
        _logger.info(f"Creando orden {i+1} de {count}")
        order = create_validated_lab_order(env)
        orders |= order
        
        # Variar las observaciones
        if i == 1:
            order.lab_notes = "Paciente diabético tipo 2. Control mensual de glucemia."
        elif i == 2:
            order.lab_notes = "Control post-operatorio. Paciente con antecedentes de anemia."
    
    return orders


if __name__ == '__main__':
    # Configuración
    db_name = 'lims_demo'
    
    # Conectar a Odoo
    odoo.tools.config.parse_config(['--database', db_name])
    
    # Obtener el registro de la base de datos
    registry = odoo.registry(db_name)
    
    # Crear cursor y environment
    with registry.cursor() as cr:
        env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
        
        try:
            # Crear órdenes con resultados validados
            orders = create_multiple_test_orders(env, count=2)
            
            # Confirmar cambios
            cr.commit()
            
            print(f"\n✅ Se crearon {len(orders)} órdenes de laboratorio con resultados validados:")
            for order in orders:
                print(f"   - {order.name}: {order.partner_id.name}")
                print(f"     Pruebas: {', '.join(test.product_id.name for test in order.lab_test_ids)}")
            
            print("\n📋 Ahora puedes probar el botón 'Imprimir Informe de Resultados' en estas órdenes.")
            
        except Exception as e:
            cr.rollback()
            print(f"\n❌ Error: {str(e)}")
            _logger.error(f"Error creando datos demo: {str(e)}", exc_info=True)