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

import re

from odoo import models, fields, api

from odoo.exceptions import ValidationError
from odoo.tools import ustr

from logging import getLogger
_logger = getLogger(__name__)

ls_tipo_organizacion = [('publica', 'Pública'),
                        ('privada', 'Privada')]


class SgtResPartner(models.Model):
    _inherit = 'res.partner'
    _sql_constraints = [('unique_cedula', 'UNIQUE(cedula)', 'El número de cédula ya está registrado'),
                        ('unique_rif', 'UNIQUE(rif)', 'El número de rif ya está registrado'),
                        ('unique_correo', 'UNIQUE(email)', 'El Correo Electronico ya está registrado')]

    numero_contribuyente = fields.Char(string='N° de Aportante', readonly='True', help='Número del contribuyente fidetel')
    fiscal_figure_id = fields.Many2one('sgt_figura_fiscal', string='Figura Fiscal')
    country_id = fields.Many2one(default=lambda self: self.env['res.country'].search([('name', '=', 'Venezuela')]), readonly=True, string='País')
    sujeto_pasivo_ids = fields.Many2many('res.partner', 'res_partner_rel', 'res_partner_inv', 'res_partner_com', string='Responsables')
    empresa_count = fields.Integer(string='Empresas', compute='calcular_empresas')
    display_registro = fields.Char(store=True)
    is_responsable = fields.Boolean(string='Responsable')
    is_contribuyente = fields.Boolean(string='Contribuyente')
    name = fields.Char(readonly=False, size=100)
    cedula = fields.Char(string='Cédula', size=10)
    first_name = fields.Char(string='Primer Nombre', size=35)
    second_name = fields.Char(string='Segundo Nombre', size=35)
    first_last_name = fields.Char(string='Primer Apellido', size=35)
    second_last_name = fields.Char(string='Segundo Apellido', size=35)
    gender = fields.Selection([('femenino', 'Femenino'), ('masculino', 'Masculino')], string='Género')
    rif = fields.Char(string='RIF', size=10)
    denominacion_comercial = fields.Char(string='Denominación', size=40)
    actividad_economica_id = fields.Many2one('sgt_actividad_economica', string='Actividad Económica')
    numero_licencia = fields.Char(string='N° Licencia', size=30)
    fecha_registro = fields.Date(string='Fecha del Registro')
    numero_registro = fields.Char(string='Número')
    folio = fields.Char(string='Folio')
    tomo = fields.Char(string='Tomo')
    fecha_operaciones = fields.Date(string='Fecha de Operaciones')
    representante_legal_ids = fields.Many2many('res.partner', 'representante_rel', 'res_partner_inv', 'res_partner_com', string='Representante Legal')
    analista_verificacion_ids = fields.One2many('sgt_analista_verificacion', 'res_partner_id', 'Verifaciones')
    company_type = fields.Selection(selection=[('person', 'Natural'), ('company', 'Jurídico')], store=True)
    tipo_organizacion = fields.Selection(ls_tipo_organizacion, string='Tipo de Organización')
    adjunto_uno = fields.Binary('Adjunto N°1')
    adjunto_dos = fields.Binary('Adjunto N°2')
    adjunto_tres = fields.Binary('Adjunto N°3')
    adjunto_cuatro = fields.Binary('Adjunto N°4')
    adjunto_cinco = fields.Binary('Adjunto N°5')

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

    @api.multi
    def write_boolean(self, ids):
        for i in ids:
            if not i.is_responsable:
                i.write({'is_responsable': True})

    @api.multi
    def write(self, vals):
        if self.representante_legal_ids or self.sujeto_pasivo_ids:
            self.write_boolean(self.representante_legal_ids)
            self.write_boolean(self.sujeto_pasivo_ids)
        if vals.get('primer_nombre'):
            vals.update({'primer_nombre': vals.get('primer_nombre').title()})
        if vals.get('primer_apellido'):
            vals.update({'primer_apellido': vals.get('primer_apellido').title()})
        if vals.get('razon_social'):
            vals.update({'razon_social': vals.get('razon_social').title()})
        if vals.get('fiscal_figure_id'):
            ffiscal = self.env['sgt_figura_fiscal'].search([('id', '=', vals.get('fiscal_figure_id'))])
            if vals.get('rif') and vals.get('fiscal_figure_id'):
                vals['display_registro'] = ustr(ffiscal.codigo) + '-' + ustr(vals.get('rif'))
            elif vals.get('cedula') and vals.get('fiscal_figure_id'):
                vals['display_registro'] = ustr(ffiscal.codigo) + '-' + ustr(vals.get('cedula'))
        return super(SgtResPartner, self).write(vals)

    @api.multi
    def calcular_empresas(self):
        # Calcular todas las empresas asociadas a una identificadora
        for empresa in self:
            empresas = self.env['res.partner'].search([('is_company', '=', True), ('sujeto_pasivo_ids', '=', self.id)])
            empresa_representante = self.env['res.partner'].search([('is_company', '=', True), ('representante_legal_ids', '=', self.id)])
            empresa.empresa_count = len(empresas)
            empresa.empresa_count += len(empresa_representante)

    @api.multi
    def ver_empresas(self):
        # Función llamada en la vista, retorna la vista de las empresas asociadas a una persona.
        self.ensure_one()
        return {
            'name': 'Empresas asociadas a {0} {1}'.format(self.first_name.encode('utf-8'), self.first_last_name.encode('utf-8')),
            'create': False,
            'view_mode': 'tree',
            'view_id': self.env.ref('kyb_sgt_ruc.view_partner_tree_contribuyente').id,
            'view_type': 'form',
            'res_model': 'res.partner',
            'type': 'ir.actions.act_window',
            'target': 'new',
            'domain': ['|', ('sujeto_pasivo_ids', '=', self.id), ('representante_legal_ids', '=', self.id)],
            'context': {},
        }

    @api.model
    def create(self, values):
        # Valida si son representantes legales o responsbles, Para la creación de un correlativo en numero_contribuyente.
        # _logger.info('\n\n\n\n %s \n\n\n\n' % values)
        if values.get('first_name'):
            values.update({'first_name': values.get('first_name').title()})
        if values.get('first_last_name'):
            values.update({'first_last_name': values.get('first_last_name').title()})
        if values.get('name'):
            values.update({'name': values.get('name').title()})
        if values.get('is_contribuyente'):
            values.update({'numero_contribuyente': self.env['ir.sequence'].next_by_code('res.partner')})
        if self.representante_legal_ids or self.sujeto_pasivo_ids:
            self.write_boolean(self.representante_legal_ids)
            self.write_boolean(self.sujeto_pasivo_ids)
        if values.get('fiscal_figure_id'):
            ffiscal = self.env['sgt_figura_fiscal'].search([('id', '=', values.get('fiscal_figure_id'))])
            if values.get('rif') and values.get('fiscal_figure_id'):
                values['display_registro'] = ustr(ffiscal.codigo) + '-' + ustr(values.get('rif'))
            elif values.get('cedula') and values.get('fiscal_figure_id'):
                values['display_registro'] = ustr(ffiscal.codigo) + '-' + ustr(values.get('cedula'))
        return super(SgtResPartner, self).create(values)

    @api.constrains('cedula', 'rif')
    def numero_identificacion(self):
        # Validar que el número de cédula tenga solo valores numéricos
        if self.cedula:
            if not self.cedula.isdigit():
                raise ValidationError("El número de cédula debe contener solo valores númericos")
        elif self.rif:
            if not self.rif.isdigit():
                raise ValidationError("El número de rif debe contener solo valores númericos")

    @api.constrains('folio', 'tomo', 'numero_registro')
    def registro_mercantil(self):
        if self.folio:
            if not self.folio.isdigit():
                raise ValidationError("El número de Folio debe contener solo valores númericos")
        if self.tomo:
            if not self.tomo.isdigit():
                raise ValidationError("El número de Tomo debe contener solo valores númericos")
        if self.numero_registro:
            if not self.numero_registro.isdigit():
                raise ValidationError("El número de Registro debe contener solo valores númericos")

    @api.constrains('email')
    def formato_email(self):
        # Validar que el email tenga un arroba
        if self.email:
            if not re.match('^[(a-z0-9\_\-\.)]+@[(a-z0-9\_\-\.)]+\.[(a-z)]{2,15}$', self.email.lower()):
                raise ValidationError(('Formato de email invalido \n %s \n La forma correcta es: ejemplo@dominio.com' % (self.email).encode('utf-8')))

    @api.constrains('first_name', 'first_last_name')
    def primer_nombre(self):
        # Validar que el Primer Nombre y Primer Apellido solo sean valores alfabeticos
        if self.first_name:
            if not self.first_name.isalpha():
                raise ValidationError("El primer nombre debe contener solo valores alfabeticos")
        if self.first_last_name:
            if not self.first_last_name.isalpha():
                raise ValidationError("El primer apellido debe contener solo valores alfabeticos")

    @api.constrains('phone', 'mobile')
    def numero_telefonico(self):
        # Validar que el número telefónico tenga solo valores numéricos.
        if self.phone:
            if not self.phone.isdigit():
                raise ValidationError("El número de telefóno debe contener solo valores numéricos")
        if self.mobile:
            if not self.mobile.isdigit():
                raise ValidationError("El número de móvil debe contener solo valores numéricos")
    """
    @api.constrains('sujeto_pasivo_ids')
    def _check_responsables(self):
        # Validar que se registren al menos 3 responsables
        responsables = len(self.sujeto_pasivo_ids)
        print self.is_contribuyente
        if self.is_contribuyente:
            if responsables < 3:
                raise ValidationError("Debe registrar al menos 3 responsables")
    """

    @api.onchange('first_name', 'second_name', 'first_last_name', 'second_last_name', 'name', 'denominacion_comercial')
    def title_char(self):
        for char in self:
            if char.first_name:
                char.first_name = char.first_name.title()
            if char.second_name:
                char.second_name = char.second_name.title()
            if char.first_last_name:
                char.first_last_name = char.first_last_name.title()
            if char.second_last_name:
                char.second_last_name = char.second_last_name.title()
            if char.name:
                char.name = char.name.title()
            if char.denominacion_comercial:
                char.denominacion_comercial = char.denominacion_comercial.title()

    @api.onchange('first_name', 'first_last_name')
    def concatenate_name(self):
        # Concatenar en el name el primer nombre y el primer apellido de la persona
        for name in self:
            if name.first_name and name.first_last_name:
                name.name = name.first_name.title() + ' ' + name.first_last_name.title()

    @api.onchange('state_id')
    # Limpiar los campos de minicipio y parroquia cuando selecciono un estado diferente
    def _onchange_limpiar_state(self):
        self.municipality_id = ''
        self.parish_id = ''

    @api.onchange('municipality_id')
    # Limpiar el campo de parroquia cuando selecciono un municipio diferente
    def _onchange_limpiar_municipality(self):
        self.parish_id = ''

    @api.onchange('company_type')
    # Limpiar el campo de Figura Fiscal
    def _onchange_limpiar_company(self):
        self.fiscal_figure_id = ''

    @api.multi
    @api.depends('fiscal_figure_id')
    def verificar_tipo_organizacion(self):
        if self.fiscal_figure_id.codigo == 'J':
            self.tipo_organizacion = 'privada'
        elif self.fiscal_figure_id.codigo == 'G' or self.fiscal_figure_id.codigo == 'C':
            self.tipo_organizacion = 'publica'
        else:
            self.tipo_organizacion = 'privada'
