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

from odoo import models, fields, api
from odoo.tools.translate import _
from odoo.exceptions import ValidationError
from odoo.exceptions import UserError


class HrTicketing(models.Model):
    _name = 'hr.ticket.request'
    _rec_name = 'employee_id'
    _description = 'Ticket Request'
    _inherit = ['mail.thread']

    STATE_SELECTION = [
        ('draft', _('Draft')),
        ('submit', _('Direct Manager')),
        ('review', _('Government Relations')),
        ('confirm', _('HR Manager')),
        ('done', _('Financial Manager')),
        ('refuse', _('Refused')),
        #   ('cancelled', _('Cancelled')),
    ]

    from_hr = fields.Boolean(_('Another Employee'))
    estimated_ticket_amount = fields.Float(_('Estimated Cost of Ticket'), )
    contract_type = fields.Selection([('single', 'Single'),
                                      ('marriage', 'Married'),
                                      ], string='Contract Type', )
    contract_start_date = fields.Date(string='Contract Start Date', related='employee_id.contract_id.date_start',
                                      readonly=True)
    contract_end_date = fields.Date(string='Contract End Date', related='employee_id.contract_id.date_end',
                                    readonly=True)
    contract_duration = fields.Selection(related='employee_id.contract_id.contract_duration', readonly=True)

    ticket_degree = fields.Selection([
        ('first', 'First'),
        ('first_reduced', 'First reduced'),
        ('economic', 'Economic'),
        ('business', 'Business'),
        ('other', 'Other'),
    ], string='Tickets Degree')

    request_for = fields.Selection(
        [('employee', 'For Employee Only'), ('family', 'For Family Only'), ('all', 'For Employee and Family'), ],
        _('Request For'))
    note = fields.Text(string='Notes')
    state = fields.Selection(STATE_SELECTION, string='Status', default='draft', tracking=True)
    leave_ticket = fields.Boolean(string='Leave Ticket')
    passport_issue_place = fields.Char(related='employee_id.place_issuance_passport', string='Passport Issue Place')
    passport_issue_date = fields.Date(related='employee_id.date_issuance_passport', string='Passport Issue Date')
    passport_expiry_date = fields.Date(related='employee_id.expiration_date_passport', string="Passport Expiry Date")
    position_type = fields.Selection([
        ('Consultant_director', 'Managerial'),
        ('normal', 'Normal Job')
    ], string='Position Type')
    request_date = fields.Date(string='Request Date', default=fields.Date.today)
    cost_of_tickets = fields.Float(string='Cost Of Tickets')

    # Relational fields
    employee_id = fields.Many2one('hr.employee', string='Employee', default=lambda self: self._employee_get())
    company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
    travel_agent = fields.Many2one('airline.agent', string='Travel Agent')
    journal_id = fields.Many2one('account.journal', _('Journal'))
    validators_user_ids = fields.Many2many('res.users', string='Validators')
    # passport_no = fields.Many2one('hr.employee.dependent', string='Passport No.', readonly=True)
    passport_no = fields.Many2one(related='employee_id.passport_id')
    request_type = fields.Many2one('hr.ticket.request.type')
    ticket_check = fields.Boolean(related='request_type.ticket_check')
    air_line = fields.Many2one('hr.airline', string='AirLine')
    attach_ids = fields.One2many('ir.attachment', 'ticket_request_id', string='Attachment')

    job_id = fields.Many2one('hr.job', string='Job Title', related='employee_id.job_id', readonly=True)
    department_id = fields.Many2one('hr.department', string='Department', related='employee_id.department_id',
                                    readonly=True)
    nationality_id = fields.Many2one('res.country', string='Nationality', related='employee_id.country_id',
                                     readonly=True)
    employee_dependant = fields.One2many('hr.employee.dependent', 'contract_id', readonly=True,
                                         related='employee_id.contract_id.employee_dependant')
    move_id = fields.Many2one('account.move')
    mission_check = fields.Boolean()
    ticket_date = fields.Date(string='Ticket Date')
    destination = fields.Many2one('mission.destination', string='Destination')

    def unlink(self):
        for item in self:
            if item.state != 'draft':
                raise UserError(_('You can not delete record in state not in draft'))
        return super(HrTicketing, self).unlink()

    def submit(self):
        #if self.employee_id and self.request_for:
            #if self.employee_id.marital == 'single' and self.request_for in ['family', 'all']:
               # raise ValidationError(_('You are single, can not request ticket for family'))
        self.write({'state': 'submit'})

    def review(self):
        self.write({'state': 'review'})

    def confirm(self):
        self.write({'state': 'confirm'})

    def action_done(self):
        if self.cost_of_tickets > 0:
            debit_line_vals = {
                'name': 'debit',
                'debit': self.cost_of_tickets,
                'date': self.request_date,
                'account_id': self.request_type.account_debit_id.id,
                'partner_id': self.employee_id.user_id.partner_id.id,
                'analytic_account_id': self.request_type.analytic_account_id.id,
            }
            credit_line_vals = {
                'name': 'credit',
                'credit': self.cost_of_tickets,
                'date': self.request_date,
                'account_id': self.journal_id.default_account_id.id,
                'partner_id': self.employee_id.user_id.partner_id.id
            }
            if not self.move_id :
               move_id = self.env['account.move'].create({
                   'state': 'draft',
                   'journal_id': self.journal_id.id,
                   'date': self.request_date,
                   'ref': 'Ticket Request for %s' % self.employee_id.name,
                   'line_ids': [(0, 0, debit_line_vals), (0, 0, credit_line_vals)],
                   'res_model': 'hr.ticket.request',
                   'res_id': self.id
               })

               self.write({
                   'state': 'done',
                   'move_id': move_id.id
               })
        else:
            self.write({'state': 'done'})

    def refuse(self):
        self.write({'state': 'refuse'})

    #
    # def cancel(self):
    #  self.write({'state': 'cancelled'})

    def re_draft(self):
        # when redraft cancel the created account move
        if self.move_id:
            if self.move_id.state == 'draft':
                # self.move_id.write({'state': 'canceled'})
                self.move_id.unlink()
                self.write({
                    'state': 'draft',
                    'move_id': False
                })
            else:
                raise UserError(
                    _('You can not cancel account move "%s" in state not draft') % self.move_id.name)
        else:
            self.state = 'draft'

    @api.model
    def _employee_get(self):
        employees = self.env['hr.employee'].search([('user_id', '=', self._uid)])
        if len(employees) <= 0:
            raise ValidationError(_('Set This User For Employee Profile'))
        else:
            # if employees[0].contract_id and employees[0].contract_id.emp_type and employees[
            #     0].contract_id.emp_type == 'saudi':
            # raise ValidationError(_('Not allowed to request tickets for the Saudis Employees'))
            return employees[0]

    @api.constrains('request_for')
    def check_request(self):
        if self.employee_id and self.request_for:
            if self.employee_id.marital == 'single' and self.request_for in ['family', 'all']:
                raise ValidationError(_('You are single, can not request ticket for family'))

    # Calculate salary rule on change leave type and save it in cost_of_tickets
    @api.onchange('request_type', 'employee_id', 'destination')
    def calculate_cost_of_tickets(self):
        for item in self:
            item.cost_of_tickets = 0.0
            if item.request_type:
                if item.request_type.allowance_name:
                    if item.employee_id:
                        if item.employee_id.contract_id:
                            item.cost_of_tickets = item.compute_rule(item.request_type.allowance_name,
                                                                     item.employee_id.contract_id)
                        else:
                            raise UserError(_('Employee "%s" has no contract') % item.employee_id.name)

                else:
                    if item.destination and item.employee_id:
                        if item.employee_id.contract_id:
                            employee_class = item.employee_id.contract_id.ticket_class_id
                            if employee_class:
                                for line in item.destination.class_ids:
                                    if employee_class == line.ticket_class_id:
                                        item.cost_of_tickets = line.price
                        else:
                            raise UserError(_('Employee "%s" has no contract') % item.employee_id.name)

    # Compute salary rules

    def compute_rule(self, rule, contract):
        localdict = dict(employee=contract.employee_id, contract=contract)

        if rule.amount_select == 'percentage':
            total_percent = 0
            if rule.related_benefits_discounts:
                for line in rule.related_benefits_discounts:
                    if line.amount_select == 'fix':
                        total_percent += self.compute_rule(line, contract)
                    elif line.amount_select == 'percentage':
                        total_percent += self.compute_rule(line, contract)
                    else:
                        total_percent += self.compute_rule(line, contract)
            if total_percent:
                if rule.salary_type == 'fixed':
                    try:
                        return float(total_percent * rule.amount_percentage / 100)
                    except:
                        raise UserError(
                            _('Wrong percentage base or quantity defined for salary rule %s (%s).') % (
                                rule.name, rule.code))
                elif rule.salary_type == 'related_levels':
                    levels_ids = rule.salary_amount_ids.filtered(
                        lambda item: item.salary_scale_level.id == contract.salary_level.id)
                    if levels_ids:
                        for l in levels_ids:
                            try:
                                return float(l.salary * total_percent / 100)
                            except:
                                raise UserError(
                                    _('Wrong quantity defined for salary rule %s (%s).') % (
                                        rule.name, rule.code))
                    else:
                        return 0
                elif rule.salary_type == 'related_groups':
                    groups_ids = rule.salary_amount_ids.filtered(
                        lambda item: item.salary_scale_group.id == contract.salary_group.id)
                    if groups_ids:
                        for g in groups_ids:
                            try:
                                return float(g.salary * total_percent / 100)
                            except:
                                raise UserError(
                                    _('Wrong quantity defined for salary rule %s (%s).') % (
                                        rule.name, rule.code))
                    else:
                        return 0
                elif rule.salary_type == 'related_degrees':
                    degrees_ids = rule.salary_amount_ids.filtered(
                        lambda item: item.salary_scale_degree.id == contract.salary_degree.id)
                    if degrees_ids:
                        for d in degrees_ids:
                            try:
                                return float(d.salary * total_percent / 100)
                            except:
                                raise UserError(
                                    _('Wrong quantity defined for salary rule %s (%s).') % (
                                        rule.name, rule.code))
                    else:
                        return 0
            else:
                try:
                    return 0
                except:
                    raise UserError(_('There is no total for rule : %s') % (rule.name))

        elif rule.amount_select == 'fix':
            return rule._compute_rule(localdict)[0]

        else:
            return rule._compute_rule(localdict)[0]


class Attachment(models.Model):
    _inherit = 'ir.attachment'

    # Relational fields
    ticket_request_id = fields.Many2one(comodel_name='hr.ticket.request')


class hr_airline(models.Model):
    _name = 'hr.airline'

    name = fields.Char(string='Name')
    ar_name = fields.Char(string='Arabic Name')
    code = fields.Char(string='Code')

    # Relational fields
    company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)


class hr_airline_city(models.Model):
    _name = 'hr.airline.city'

    name = fields.Char(string='Name')
    ar_name = fields.Char(string='Arabic Name')
    code = fields.Char(string='Code')

    # Relational fields
    company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)


class HRTicketDependent(models.Model):
    _inherit = 'hr.ticket.dependent'

    ticket_request_line = fields.Many2one(comodel_name='hr.ticket.request')


class airline_agent(models.Model):
    _name = 'airline.agent'
    _rec_name = 'agent_name'

    agent_name = fields.Char(string='Agent Name')
    ar_agent_name = fields.Char(string='Arabic Agent Name')
    account_no = fields.Char(string='Account No.')
    code = fields.Char(string='Code')
    telephone = fields.Char(string='Telephone')
    mobile = fields.Char(string='Mobile')
    fax = fields.Char(string='Fax No.')
    mail = fields.Char(string='E-mail')
    contact_person = fields.Char(string='Contact Person')
    sur_name = fields.Selection([('mr', 'Mr'), ('mrs', 'Mrs'), ('president', 'President')], string='Sur Name')
    # Relational fields
    company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)

    _sql_constraints = [
        ('code_code_unique', 'unique(code)', 'The agency code must be unique per company !'),
    ]


class HrTicketingType(models.Model):
    _name = 'hr.ticket.request.type'

    name = fields.Char()
    ticket_check = fields.Boolean()

    # relational fields
    allowance_name = fields.Many2one('hr.salary.rule', domain=[('category_id.rule_type', '=', 'allowance')])
    account_debit_id = fields.Many2one('account.account')
    analytic_account_id = fields.Many2one(comodel_name='account.analytic.account',string='Analytic Account')
    company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
