# -*- coding: utf-8 -*-

from odoo import models, fields, api


class SkeenInventarioItem(models.Model):
    _name = 'skeen.inventario.item'
    _description = 'Item de Inventario / Consumible SKEEN'
    _order = 'name asc'

    name = fields.Char(string='Nombre', required=True, index=True)
    kind = fields.Selection([
        ('producto', 'Producto'),
        ('consumible', 'Consumible'),
    ], string='Tipo', required=True, default='producto', index=True)
    sku = fields.Char(string='SKU / Código', index=True)
    category = fields.Char(string='Línea / Categoría')
    unit = fields.Char(string='Unidad', default='pieza')

    qty = fields.Float(string='Existencia', default=0.0)
    qty_optimal = fields.Float(string='Nivel óptimo', default=0.0)
    qty_min = fields.Float(string='Stock mínimo', default=0.0)

    cost = fields.Float(string='Costo unitario', default=0.0)
    price = fields.Float(string='Precio venta', default=0.0)
    inventory_value = fields.Float(string='Valor inventario', compute='_compute_value', store=True)

    expiry_date = fields.Date(string='Caducidad')
    last_count_date = fields.Date(string='Último conteo físico')
    active = fields.Boolean(string='Activo', default=True)
    genera_monedero = fields.Boolean(string='Genera monedero', default=True,
                                     help='Si está activo, la venta de este artículo acumula puntos monedero.')
    notes = fields.Text(string='Notas')

    move_ids = fields.One2many('skeen.inventario.move', 'item_id', string='Movimientos')
    stock_level = fields.Selection([
        ('out', 'Sin existencias'),
        ('critical', 'Crítico'),
        ('low', 'Bajo'),
        ('optimal', 'Óptimo'),
    ], string='Nivel', compute='_compute_level', store=True)

    @api.depends('qty', 'cost')
    def _compute_value(self):
        for rec in self:
            rec.inventory_value = (rec.qty or 0.0) * (rec.cost or 0.0)

    @api.depends('qty', 'qty_min', 'qty_optimal')
    def _compute_level(self):
        for rec in self:
            q = rec.qty or 0.0
            if q <= 0:
                rec.stock_level = 'out'
            elif rec.qty_min and q <= rec.qty_min:
                rec.stock_level = 'critical'
            elif rec.qty_optimal and q < rec.qty_optimal:
                rec.stock_level = 'low'
            else:
                rec.stock_level = 'optimal'

    @api.model
    def _cron_descontar_caducados(self):
        """Descuenta (baja a cero) los artículos caducados con existencias.
        Corre diario vía ir.cron; la baja queda como movimiento tipo 'baja'."""
        hoy = fields.Date.today()
        caducados = self.search([
            ('expiry_date', '!=', False),
            ('expiry_date', '<', hoy),
            ('qty', '>', 0),
            ('active', '=', True),
        ])
        Move = self.env['skeen.inventario.move'].sudo()
        for item in caducados:
            Move.create({
                'item_id': item.id,
                'type': 'baja',
                'qty': item.qty,
                'reference': 'CADUCIDAD',
                'notes': f'Descuento automático por caducidad {item.expiry_date}',
            })
        if caducados:
            import logging
            logging.getLogger(__name__).info(
                'Inventario: %s artículos caducados descontados', len(caducados))
        return len(caducados)


class SkeenInventarioMove(models.Model):
    _name = 'skeen.inventario.move'
    _description = 'Movimiento de Inventario SKEEN'
    _order = 'date desc, id desc'

    item_id = fields.Many2one('skeen.inventario.item', string='Item', required=True, ondelete='cascade', index=True)
    type = fields.Selection([
        ('compra', 'Compra (entrada)'),
        ('venta', 'Venta (salida)'),
        ('baja', 'Baja (merma)'),
        ('ajuste', 'Ajuste (conteo físico)'),
    ], string='Tipo', required=True)
    qty = fields.Float(string='Cantidad', required=True, default=0.0)
    before_qty = fields.Float(string='Existencia anterior', readonly=True)
    after_qty = fields.Float(string='Existencia resultante', readonly=True)
    date = fields.Datetime(string='Fecha', default=fields.Datetime.now)
    reference = fields.Char(string='Referencia')
    notes = fields.Char(string='Notas')

    @api.model_create_multi
    def create(self, vals_list):
        moves = super().create(vals_list)
        for m in moves:
            item = m.item_id
            if not item:
                continue
            before = item.qty or 0.0
            q = m.qty or 0.0
            if m.type == 'compra':
                after = before + q
            elif m.type in ('venta', 'baja'):
                after = before - q
            elif m.type == 'ajuste':
                after = q  # ajuste fija la existencia al valor del conteo
            else:
                after = before
            after = max(0.0, after)
            item.write({'qty': after, 'last_count_date': fields.Date.today() if m.type == 'ajuste' else item.last_count_date})
            m.write({'before_qty': before, 'after_qty': after})
        return moves
