from odoo import models, fields, api, _, SUPERUSER_ID
import random
from datetime import datetime, timedelta
from odoo.tools import email_re, email_escape_char, email_split
from odoo.exceptions import UserError,ValidationError
from odoo.tools import email_re
import uuid
import pytz
import logging
_logger = logging.getLogger(__name__)



class HelpdeskTicket(models.Model):
    _inherit = 'helpdesk.ticket'

    erp_id = fields.Many2one('erp.modules','Módulo')
    incidence_type = fields.Selection([
        ('odoo', 'Falla Odoo Nacional'),
        ('mclick','Falla Morsa Click Nacional'),
        ('suc','Sucursal detenida'),
        ('internet_fail','Falla General de Internet'),
        ('slow_odoo','Lentitud en Odoo'),
    ],string="Incidencia")
    warehouse_id = fields.Many2one('warehouse.helpdesk','Sucursal')
    call_before_10 = fields.Boolean('Atención antes de 10 minutos')
    color  = fields.Integer('Color',compute="_get_color")
    erp_type = fields.Selection([
        ('soporte','Soporte'),
        ('mejora','Mejora'),
        ('reporte','Reporte')
    ],string="Tipo de asistencia")
    ticket_reason = fields.Many2one('ticket.reason','Motivo de Ticket',
        default=lambda self: self.env['ticket.reason'].search([('name','=','Ninguno'),],limit=1).id
    )
    problem_solved_on_time = fields.Boolean('¿Solucionamos complementame tu problema?')
    good_service_actitude = fields.Boolean('¿Ha sido buena nuestra actitud de Servicio?')
    begin_before_ten_min  = fields.Boolean('¿COmenzamos a atenderte antes de 10 minutos?')
    is_support = fields.Boolean('Es soporte',compute='_compute_ticket_type')
    is_erp = fields.Boolean('Es ERP',compute='_compute_ticket_type')
    is_emergency = fields.Boolean('Es 911',compute='_compute_ticket_type') 
    user_branch_id = fields.Many2one('warehouse.helpdesk', related="partner_id.user_ids.warehouse_id", string='Usuario Sucursal', store=True)
    user_region_id = fields.Many2one('region.helpdesk', related="user_branch_id.region_id", string="Región", store=True,)
    user_id = fields.Many2one('res.users',string="Usuario Asignado", tracking=True,domain="[('id','in',team_members)]")
    team_members = fields.Many2many('res.users',relation="team_members_user_rel",related="team_id.team_members")
    module_route = fields.Char("Ruta de la transacción")
    process_text = fields.Char("¿En que proceso utilizas la transacción?")
    required_validation = fields.Char("Cuales son las validaciones que se requieren")
    common_scenery = fields.Char("¿Qué escenarios son comunes a trabajar con esta transacción?")
    module_impact = fields.Char("¿Tu solicitud, impacta de algún modo a algún otro Módulo?")
    system_id = fields.Many2one('erp.system','Sistema')
    team_admin_id = fields.Many2one('res.users',string="Administrador del equipo",related='team_id.team_admin_id')
    comp_morsa = fields.Selection(related="partner_id.user_ids.comp_morsa",string='Empresa')
    
    
    def _get_color(self):
        in_progress_stage = self.env.ref('sh_all_in_one_helpdesk.in_progress_stage').id
        new_stage = self.env.ref('sh_all_in_one_helpdesk.new_stage').id
        ten_min = self.env.ref('helpdesk_morsa.response_10_minutes').id

        simple_time = float(self.env['ir.config_parameter'].sudo().get_param('helpdesk_morsa.time_simple_alert'))
        medium_time = float(self.env['ir.config_parameter'].sudo().get_param('helpdesk_morsa.time_medium_alert'))
        extreme_time = float(self.env['ir.config_parameter'].sudo().get_param('helpdesk_morsa.time_extreme_alert'))

        for rec in self:
            if rec.team_head:
                rec.color = 10
                if rec.is_support == True or rec.is_emergency == True:
                    if fields.Datetime.now() >= rec.create_date+timedelta(hours=simple_time) and fields.Datetime.now() < rec.create_date+timedelta(hours=medium_time) and rec.stage_id.id in [new_stage]:
                        rec.color = self.env['ir.config_parameter'].sudo().get_param('helpdesk_morsa.color_simple_alert')
                    elif fields.Datetime.now() >= rec.create_date+timedelta(hours=medium_time) and fields.Datetime.now() < rec.create_date+timedelta(hours=extreme_time) and rec.stage_id.id in [new_stage,ten_min]:
                        rec.color = self.env['ir.config_parameter'].sudo().get_param('helpdesk_morsa.color_medium_alert')
                    elif fields.Datetime.now() >= rec.create_date+timedelta(hours=extreme_time) and rec.stage_id.id in [new_stage,ten_min,in_progress_stage]:
                        rec.color = self.env['ir.config_parameter'].sudo().get_param('helpdesk_morsa.color_extreme_alert')
            else:
                rec.color = 10
                    

    @api.depends('team_id')
    def _compute_ticket_type(self):
        for ticket in self:
            if ticket.team_id.id == self.env.ref('helpdesk_morsa.techinnical_support').id:
                ticket.is_support = True
            else:
                ticket.is_support = False
                
            if ticket.team_id.id == self.env.ref('helpdesk_morsa.erp_asistense').id:
                ticket.is_erp = True
            else:
                ticket.is_erp = False

            if ticket.team_id.id == self.env.ref('helpdesk_morsa.ti_emergency').id:
                ticket.is_emergency = True
            else:
                ticket.is_emergency = False
           
    def assign_me(self):
        self.user_id = self.env.user.id


    @api.onchange('team_id')
    def onchange_ticket_type(self):
        if self.team_id and not self.ticket_type:
            self.ticket_type = self.team_id.helpdesk_ticket_type_id.id
        elif self.team_id and self.ticket_type:
            self.ticket_type = self.team_id.helpdesk_ticket_type_id.id

    @api.onchange('ticket_type')
    def onchange_ticket_team(self):
        if self.ticket_type and not self.team_id:
            self.team_id = self.env['helpdesk.team'].search([('helpdesk_ticket_type_id','=',self.ticket_type.id)]).id
        elif self.team_id and self.ticket_type:
            self.team_id = self.env['helpdesk.team'].search([('helpdesk_ticket_type_id','=',self.ticket_type.id)]).id
          

    @api.onchange('partner_id')
    def onchange_partner_simple_info(self):
        if self.partner_id:
            if self.partner_id.phone:
                self.mobile_no = self.partner_id.phone
            elif self.partner_id.mobile:
                self.mobile_no = self.partner_id.mobile

    
    def _compute_access_url(self):
        super(HelpdeskTicket, self)._compute_access_url()
        for ticket in self:
            if ticket.team_id.id == self.env.ref('helpdesk_morsa.techinnical_support').id:
                ticket.access_url = '/my/soporte/%s' % (ticket.id)
            elif ticket.team_id.id == self.env.ref('helpdesk_morsa.erp_asistense').id:
                ticket.access_url = '/my/erp/%s' % (ticket.id)
            elif ticket.team_id.id == self.env.ref('helpdesk_morsa.ti_emergency').id:
                ticket.access_url = '/my/911/%s' % (ticket.id)

    @api.model
    def create(self, vals):
        if vals.get('partner_id') == False and vals.get('email', False):
            emails = email_re.findall(vals.get('email') or '')
            email = emails and emails[0] or ''
            name = str(vals.get('email')).split('"')
            partner_id = self.env['res.partner'].create({
                'name':
                name[1],
                'email':
                email,
                'company_type':
                'person',
            })
            vals.update({
                'partner_id': partner_id.id,
                'email': email,
                'person_name': partner_id.name,
            })
        if self.env.company.sh_default_team_id and not vals.get(
                'team_id') and not vals.get('user_id'):
            vals.update({
                'team_id':
                self.env.company.sh_default_team_id.id,
                'team_head':
                self.env.company.sh_default_team_id.team_head.id,
                'user_id':
                self.env.company.sh_default_user_id.id,
            })
        
        company_id = self.env.company
        if 'company_id' in vals:
            self = self.with_company(vals['company_id'])

        if 'team_id' in vals:
            team = self.env['helpdesk.team'].sudo().search([('id','=',vals['team_id'])])
            if team.helpdesk_ticket_type_id:
                vals['ticket_type'] = team.helpdesk_ticket_type_id.id
                vals['team_head'] = team.team_head.id
            else:
                raise ValidationError(('No se pueden generar ticket, no cuenta con la configuración necesaria'))
            vals['name'] = self.env['ir.sequence'].sudo().next_by_code('helpdesk.ticket.'+str(team.id) or _('New'))
        if company_id.new_stage_id:
            vals['stage_id'] = company_id.new_stage_id.id

        vals['color'] = 10
        
        res = super(HelpdeskTicket, self).create(vals)
        
        if res.sh_sla_status_ids:
            for line in res.sh_sla_status_ids:
                line.sh_status = res.sh_status
        if res.ticket_from_website and res.company_id.new_stage_id.mail_template_ids and res.partner_id:
            for template in res.company_id.new_stage_id.mail_template_ids:
                template.sudo().send_mail(res.id, force_send=True)
        else:
            if not res.ticket_from_website and res.company_id.new_stage_id.mail_template_ids and res.partner_id:
                for template in res.company_id.new_stage_id.mail_template_ids:
                    template.sudo().send_mail(res.id, force_send=True)
        if res.team_id and res.team_head and not res.user_id:
            allocation_template = res.company_id.allocation_mail_template_id
            email_formatted = []
            if res.team_head.partner_id.email_formatted not in email_formatted:
                email_formatted.append(
                    res.team_head.partner_id.email_formatted)
            email_formatted_str = ','.join(email_formatted)
            email_values = {
                'email_from': str(res.team_head.partner_id.email_formatted),
                'email_to': email_formatted_str
            }
            if allocation_template:
                allocation_template.sudo().send_mail(res.id,
                                                     force_send=True,
                                                     email_values=email_values)
                res.ticket_allocated = True
        elif res.team_id and res.team_head and res.user_id:
            allocation_template = res.company_id.allocation_mail_template_id
            email_formatted = []
            if res.team_head.partner_id.email_formatted not in email_formatted:
                email_formatted.append(
                    res.team_head.partner_id.email_formatted)
            if res.user_id.partner_id.email_formatted not in email_formatted:
                email_formatted.append(res.user_id.partner_id.email_formatted)
            email_formatted_str = ','.join(email_formatted)
            email_values = {
                'email_from': str(res.team_head.partner_id.email_formatted),
                'email_to': email_formatted_str
            }
            if allocation_template:
                allocation_template.sudo().send_mail(res.id,
                                                     force_send=True,
                                                     email_values=email_values)
                res.ticket_allocated = True
        elif res.team_id and res.team_head and not res.user_id and res.sh_user_ids:
            allocation_template = res.company_id.allocation_mail_template_id
            email_formatted = []
            for user in res.sh_user_ids:
                if user.partner_id.email_formatted not in email_formatted:
                    email_formatted.append(user.partner_id.email_formatted)
            email_formatted_str = ','.join(email_formatted)
            email_values = {
                'email_from': str(res.team_head.partner_id.email_formatted),
                'email_to': email_formatted_str
            }
            if allocation_template:
                allocation_template.sudo().send_mail(res.id,
                                                     force_send=True,
                                                     email_values=email_values)
                res.ticket_allocated = True
        elif not res.team_id and not res.team_head and res.user_id and res.sh_user_ids:
            allocation_template = res.company_id.allocation_mail_template_id
            email_formatted = []
            if res.user_id.partner_id.email_formatted not in email_formatted:
                email_formatted.append(res.user_id.partner_id.email_formatted)
            for user in res.sh_user_ids:
                if user.id != res.user_id.id:
                    if user.partner_id.email_formatted not in email_formatted:
                        email_formatted.append(user.partner_id.email_formatted)
            email_formatted_str = ','.join(email_formatted)
            email_values = {
                'email_from': str(res.company_id.partner_id.email_formatted),
                'email_to': email_formatted_str
            }
            if allocation_template:
                allocation_template.sudo().send_mail(res.id,
                                                     force_send=True,
                                                     email_values=email_values)
                res.ticket_allocated = True
        elif not res.team_id and not res.team_head and res.user_id and not res.sh_user_ids:
            allocation_template = res.company_id.allocation_mail_template_id
            allocation_template.sudo().write({
                'email_from':
                str(res.company_id.partner_id.email_formatted),
                'email_to':
                str(res.user_id.partner_id.email_formatted),
                'partner_to':
                str(res.user_id.partner_id.id)
            })
            email_values = {
                'email_from': str(res.company_id.partner_id.email_formatted),
                'email_to': str(res.user_id.partner_id.email_formatted)
            }
            if allocation_template:
                allocation_template.sudo().send_mail(res.id,
                                                     force_send=True,
                                                     email_values=email_values)
                res.ticket_allocated = True
        elif not res.team_id and not res.team_head and not res.user_id and res.sh_user_ids:
            allocation_template = res.company_id.allocation_mail_template_id
            email_formatted = []
            for user in res.sh_user_ids:
                if user.partner_id.email_formatted not in email_formatted:
                    email_formatted.append(user.partner_id.email_formatted)
            email_formatted_str = ','.join(email_formatted)
            email_values = {
                'email_from': str(res.company_id.partner_id.email_formatted),
                'email_to': email_formatted_str
            }
            if allocation_template:
                allocation_template.sudo().send_mail(res.id,
                                                     force_send=True,
                                                     email_values=email_values)
                res.ticket_allocated = True
        if self.env.company.sh_auto_add_customer_as_follower:
            res.message_subscribe(partner_ids=res.partner_id.ids)
        res.create_initial_history_changes()
        res.append_sla_policies()
        return res


    def create_initial_history_changes(self):
        stage_history={
            'stage_task_id': self.id,
            'stage_name': self.stage_id.name,
            'date_in': datetime.now(),
            'date_in_by': self.env.user.id,
        }
        self.env['sh.helpdesk.ticket.stage.info'].sudo().create(stage_history)


    def append_sla_policies(self):
        sla = self.env['sh.helpdesk.sla'].search([
            ('sh_team_id','=',self.team_id.id),
            ('sh_ticket_type_id','=',self.ticket_type.id),
            ('sh_sla_target_type','=','reaching_stage'),
            ('sh_stage_id','!=',self.stage_id.id)
        ]).ids
        if sla:
            self.update({
                'sh_sla_policy_ids':[(6,0,sla)]
            })

    def write(self,vals):
        if self.is_support == True or self.is_erp == True or self.is_emergency == True:
            if "stage_id" in vals:
                if self.description == '<p><br></p>' or self.description==False:
                    raise ValidationError (_("Para cambiar de etapa, es necesario agregar una descripción"))
            if 'description' in  vals and vals["description"] != "" and self.description != False and vals['description'] != '<p><br></p>':
                min_description = int(self.env['ir.config_parameter'].sudo().get_param('helpdesk_morsa.description_min_lenght'))
                description = self.get_description_len(vals["description"])
                
                if description-11 < min_description:
                    raise ValidationError (_("Favor de agregar al menos "+str(min_description)+" caracteres a la descripción"))
            return super(HelpdeskTicket, self).write(vals)
        else:
            return super(HelpdeskTicket, self).write(vals)
        
    def action_approve(self):
        if self.description == '<p><br></p>' or self.description==False:
            raise ValidationError (_("Para cambiar de etapa, es necesario agregar una descripción"))
        else:
            return super(HelpdeskTicket, self).action_approve()
        
    def get_description_len(self,description):
        try:
            return len(description)
        except Exception as e:
            return 0