# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError
import logging

_logger = logging.getLogger(__name__)


class LimsTest(models.Model):
    _name = 'lims.test'
    _description = 'Prueba de Laboratorio'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _rec_name = 'name'
    _order = 'create_date desc'

    name = fields.Char(
        string='Código de Prueba',
        required=True,
        readonly=True,
        copy=False,
        default='Nuevo'
    )
    
    sale_order_line_id = fields.Many2one(
        'sale.order.line',
        string='Línea de Orden',
        required=True,
        ondelete='restrict'
    )
    
    patient_id = fields.Many2one(
        'res.partner',
        string='Paciente',
        related='sale_order_line_id.order_id.partner_id',
        store=True,
        readonly=True
    )
    
    product_id = fields.Many2one(
        'product.product',
        string='Análisis',
        related='sale_order_line_id.product_id',
        store=True,
        readonly=True
    )
    
    sample_id = fields.Many2one(
        'stock.lot',
        string='Muestra',
        domain="[('is_lab_sample', '=', True), ('patient_id', '=', patient_id), ('state', 'in', ['collected', 'in_analysis'])]",
        tracking=True
    )
    
    state = fields.Selection([
        ('draft', 'Borrador'),
        ('in_process', 'En Proceso'),
        ('result_entered', 'Resultado Ingresado'),
        ('validated', 'Validado'),
        ('cancelled', 'Cancelado')
    ], string='Estado', default='draft', tracking=True)
    
    validator_id = fields.Many2one(
        'res.users',
        string='Validador',
        readonly=True,
        tracking=True
    )
    
    validation_date = fields.Datetime(
        string='Fecha de Validación',
        readonly=True,
        tracking=True
    )
    
    technician_id = fields.Many2one(
        'res.users',
        string='Técnico',
        default=lambda self: self.env.user,
        tracking=True
    )
    
    require_validation = fields.Boolean(
        string='Requiere Validación',
        compute='_compute_require_validation',
        store=True
    )
    
    result_ids = fields.One2many(
        'lims.result',
        'test_id',
        string='Resultados'
    )
    
    notes = fields.Text(
        string='Observaciones'
    )
    
    company_id = fields.Many2one(
        'res.company',
        string='Compañía',
        required=True,
        default=lambda self: self.env.company
    )
    
    @api.depends('company_id')
    def _compute_require_validation(self):
        """Calcula si la prueba requiere validación basado en configuración."""
        IrConfig = self.env['ir.config_parameter'].sudo()
        require_validation = IrConfig.get_param('lims_management.require_validation', 'True')
        for record in self:
            record.require_validation = require_validation == 'True'
    
    @api.onchange('sale_order_line_id')
    def _onchange_sale_order_line(self):
        """Update sample domain when order line changes"""
        if self.sale_order_line_id:
            # Try to find a suitable sample from the order
            order = self.sale_order_line_id.order_id
            product = self.sale_order_line_id.product_id
            
            if order.is_lab_request and product.required_sample_type_id:
                # Find samples for this patient with the required sample type
                suitable_samples = self.env['stock.lot'].search([
                    ('is_lab_sample', '=', True),
                    ('patient_id', '=', order.partner_id.id),
                    ('sample_type_product_id', '=', product.required_sample_type_id.id),
                    ('state', 'in', ['collected', 'in_analysis'])
                ])
                
                if suitable_samples:
                    # If only one sample, select it automatically
                    if len(suitable_samples) == 1:
                        self.sample_id = suitable_samples[0]
                    # Update domain to show only suitable samples
                    return {
                        'domain': {
                            'sample_id': [
                                ('id', 'in', suitable_samples.ids)
                            ]
                        }
                    }
    
    @api.model_create_multi
    def create(self, vals_list):
        """Genera código único al crear."""
        for vals in vals_list:
            if vals.get('name', 'Nuevo') == 'Nuevo':
                vals['name'] = self.env['ir.sequence'].next_by_code('lims.test') or 'Nuevo'
        return super().create(vals_list)
    
    def action_start_process(self):
        """Inicia el proceso de análisis."""
        self.ensure_one()
        if self.state != 'draft':
            raise UserError(_('Solo se pueden procesar pruebas en estado borrador.'))
        if not self.sample_id:
            raise UserError(_('Debe asignar una muestra antes de iniciar el proceso.'))
        
        self.write({
            'state': 'in_process',
            'technician_id': self.env.user.id
        })
        
        # Log en el chatter
        self.message_post(
            body=_('Prueba iniciada por %s') % self.env.user.name,
            subject=_('Proceso Iniciado')
        )
        
        return True
    
    def action_enter_results(self):
        """Marca como resultados ingresados."""
        self.ensure_one()
        if self.state != 'in_process':
            raise UserError(_('Solo se pueden ingresar resultados en pruebas en proceso.'))
        
        if not self.result_ids:
            raise UserError(_('Debe ingresar al menos un resultado.'))
        
        # Si no requiere validación, pasar directamente a validado
        if not self.require_validation:
            self.write({
                'state': 'validated',
                'validator_id': self.env.user.id,
                'validation_date': fields.Datetime.now()
            })
            self.message_post(
                body=_('Resultados ingresados y auto-validados por %s') % self.env.user.name,
                subject=_('Resultados Validados')
            )
        else:
            self.state = 'result_entered'
            self.message_post(
                body=_('Resultados ingresados por %s') % self.env.user.name,
                subject=_('Resultados Ingresados')
            )
        
        return True
    
    def action_validate(self):
        """Valida los resultados (solo administradores)."""
        self.ensure_one()
        if self.state != 'result_entered':
            raise UserError(_('Solo se pueden validar pruebas con resultados ingresados.'))
        
        # TODO: Verificar permisos cuando se implemente seguridad
        
        self.write({
            'state': 'validated',
            'validator_id': self.env.user.id,
            'validation_date': fields.Datetime.now()
        })
        
        # Log en el chatter
        self.message_post(
            body=_('Resultados validados por %s') % self.env.user.name,
            subject=_('Resultados Validados')
        )
        
        return True
    
    def action_cancel(self):
        """Cancela la prueba."""
        self.ensure_one()
        if self.state == 'validated':
            raise UserError(_('No se pueden cancelar pruebas validadas.'))
        
        self.state = 'cancelled'
        
        # Log en el chatter
        self.message_post(
            body=_('Prueba cancelada por %s') % self.env.user.name,
            subject=_('Prueba Cancelada')
        )
        
        return True
    
    def action_draft(self):
        """Regresa a borrador."""
        self.ensure_one()
        if self.state not in ['cancelled']:
            raise UserError(_('Solo se pueden regresar a borrador pruebas canceladas.'))
        
        self.state = 'draft'
        
        return True