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

from datetime import datetime

from odoo import models, fields, api, _
from odoo.exceptions import UserError

from logging import getLogger
_logger = getLogger(__name__)

ls_tipo_movimiento = [('debito', 'Débito'),
                      ('credito', 'Crédito')]

ls_estatus_movimiento = [('borrador', 'Registrado'),
                         ('cargo', 'Cargo'),
                         ('pagado', 'Pago'),
                         ('anulado', 'Anulado')]


class SgtCuentas(models.Model):
    _name = 'sgt_cuentas'
    _rec_name = 'numero_cuenta'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    partner_id = fields.Many2one('res.partner', string='Aportante')
    state = fields.Selection([('activo', 'Activo'), ('suspendido', 'Suspendido'), ('cancelado', 'Cancelado')], string='Estatus', default="activo")
    numero_cuenta = fields.Char(string='Número de Cuenta', readonly='True', help='El codigo se genera automaticamente')
    tipo_cuenta_id = fields.Many2one('sgt_cuentas_tipos', string='Tipo de Cuenta')
    dias_mora = fields.Integer(string='Dias de Morosidad')
    saldo_corriente = fields.Float(string='Saldo Corriente', compute="calcular_saldos", store=True, digits=(12, 2))
    saldo_deudor = fields.Float(string='Saldo Deudor', compute="calcular_saldo_deudor", store=True, digits=(12, 2))
    credito_fiscal = fields.Float(string='Crédito Fiscal', compute="calcular_credito_fiscal", store=True, digits=(12, 2))
    analista_asignado_ids = fields.Many2many('res.users', 'res_users_rel', 'res_users_inv', 'res_users_com', string='Analista')
    analista_count = fields.Integer(compute='calcular_analista')
    movimientos_ids = fields.One2many('sgt_movimientos', 'cuenta_id', string='Cargos')
    ciclo_facturacion_id = fields.Many2one('sgt_ciclos_facturaciones', string='Ciclo de Facturación', default=1)

    @api.multi
    @api.depends('movimientos_ids.estatus')
    def calcular_saldos(self):
        for i in self:
            for line in i.movimientos_ids:
                if line.estatus == 'cargo' or line.estatus == 'pagado':
                    if line.tipo_movimiento == 'debito':
                        i.saldo_corriente -= line.monto_movimiento
                    elif line.tipo_movimiento == 'credito':
                        i.saldo_corriente += line.monto_movimiento
                else:
                    return

    @api.multi
    @api.depends('saldo_corriente')
    def calcular_credito_fiscal(self):
        if self.saldo_corriente > 0:
            self.credito_fiscal = self.saldo_corriente

    @api.multi
    @api.depends('saldo_corriente')
    def calcular_saldo_deudor(self):
        if self.saldo_corriente < 0:
            self.saldo_deudor = self.saldo_corriente

    @api.model
    def create(self, values):
        values.update({'numero_cuenta': self.env['ir.sequence'].next_by_code('sgt_cuentas')})
        return super(SgtCuentas, self).create(values)

    @api.multi
    def calcular_analista(self):
        # Calcular todos los analista asociadas a una cuenta
        self.ensure_one()
        self.analista_count = len(self.env['res.users'].search([('id', 'in', self.analista_asignado_ids.ids)]))

    @api.multi
    def ver_analista(self):
        # Función llamada en la vista, retorna la vista de los analistas asociadas a una cuenta .
        self.ensure_one()
        return {
            'name': 'Analista Asociados',
            'create': False,
            'view_mode': 'tree',
            'view_id': self.env.ref('kyb_sgt_cuentas.view_users_tree_ihnerit').id,
            'view_type': 'form',
            'res_model': 'res.users',
            'type': 'ir.actions.act_window',
            'target': 'new',
            'domain': [('id', 'in', self.analista_asignado_ids.ids)],
            'context': {},
        }


class SgtCiclosFacturaciones(models.Model):
    _name = 'sgt_ciclos_facturaciones'
    _rec_name = 'descripcion'
    codigo = fields.Char(string='Código', size=4)
    descripcion = fields.Char(string='Descripción', size=45)
    active = fields.Boolean(string='Activo')


class SgtCuentasTipos(models.Model):
    _name = 'sgt_cuentas_tipos'
    _rec_name = 'descripcion'
    codigo = fields.Char(string='Código', size=45)
    descripcion = fields.Char(string='Descripción', size=45)


class SgtMovimientosPeriodos(models.Model):
    _name = 'sgt_movimientos_periodos'
    _rec_name = 'periodo'
    periodo = fields.Char(string='Periodo', size=4)
    annio = fields.Char(string='Año', compute='_compute_calcular_anio')
    desde = fields.Date(string='Fecha Inicial')
    hasta = fields.Date(string='Fecha Final')
    tope = fields.Date(string='Fecha Tope')
    ciclo_facturacion_id = fields.Many2one('sgt_ciclos_facturaciones', string='Ciclo de Facturacion')

    @api.multi
    @api.depends('periodo', 'annio')
    def name_get(self):
        result = []
        for registro in self:
            name = str(registro.periodo) + '(' + str(registro.annio) + ')'
            result.append((registro.id, name))
        return result

    @api.multi
    @api.depends('desde', 'hasta')
    def _compute_calcular_anio(self):
        for i in self:
            if i.desde and i.hasta:
                date1 = datetime.strptime(i.desde, "%Y-%m-%d")
                date2 = datetime.strptime(i.hasta, "%Y-%m-%d")
                if date1.year == date2.year:
                    i.annio = str(date1.year)
                else:
                    i.annio = str(date1.year) + '-' + str(date2.year)


class SgtConceptos(models.Model):
    _name = 'sgt_conceptos'
    _rec_name = 'descripcion'
    codigo = fields.Char(string='Código', size=3)
    descripcion = fields.Char(string='Descripción', size=200)


class SgtMovimientos(models.Model):
    _name = 'sgt_movimientos'
    _rec_name = 'numero_movimiento'
    estatus = fields.Selection(ls_estatus_movimiento, string='Estatus', default='borrador')
    numero_movimiento = fields.Char(string='N° Movimiento', readonly='True', help='El codigo se genera automaticamente')
    concepto_movimiento_id = fields.Many2one('sgt_conceptos', string='Concepto')
    codigo_concepto = fields.Char(related='concepto_movimiento_id.codigo', string="Código del Concepto")
    fecha_movimiento = fields.Date(string='Fecha', readonly=True, default=datetime.today())
    tipo_movimiento = fields.Selection(ls_tipo_movimiento, string='Tipo')
    periodo_id = fields.Many2one('sgt_movimientos_periodos', string='Periodo')
    ciclo_facturacion = fields.Char(string='Ciclo de Facturación', related="periodo_id.ciclo_facturacion_id.descripcion", readonly=True)
    periodo_desde = fields.Date(string='Desde', related='periodo_id.desde', readonly=True)
    perido_hasta = fields.Date(string='Hasta', related='periodo_id.hasta', readonly=True)
    monto_movimiento = fields.Float(string='Monto', digits=(12, 2))
    descripcion = fields.Text(string='Descripcion')
    partner_id = fields.Many2one('res.partner', string='Aportante')
    cuenta_id = fields.Many2one('sgt_cuentas', string='Cuenta')
    pagado = fields.Boolean('Pagado')
    observacion = fields.Text('Observación')

    @api.model
    def create(self, values):
        values.update({'numero_movimiento': self.env['ir.sequence'].next_by_code('sgt_movimientos')})
        return super(SgtMovimientos, self).create(values)

    @api.multi
    def cambiar_cargo(self):
        self.estatus = 'cargo'

    @api.multi
    def cambiar_pago(self):
        self.estatus = 'pagado'

    @api.multi
    def cambiar_anulado(self):
        if self.observacion:
            self.estatus = 'anulado'
        else:
            raise UserError(_('El Campo de observación se encuentra vacío.'))
