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

from datetime import datetime, timedelta, date
from odoo import models, fields, api, _
from odoo.exceptions import UserError


class HrLeaveRequest(models.Model):
    _inherit = 'hr.leave'

    remaining_leaves = fields.Float(string='Remaining Legal Leaves', related='employee_id.remaining_leaves', help="Remaining legal leaves")
    overlapping_leaves = fields.Many2many('hr.leave', compute='get_overlapping_leaves', string='Overlapping Leaves', help="Overlapping leaves")
    pending_tasks = fields.One2many('pending.task', 'leave_id', string='Pending Tasks', help="Pending tasks")
    holiday_managers = fields.Many2many('res.users', compute='get_hr_holiday_managers', help="Holiday managers")
    flight_ticket = fields.One2many('hr.flight.ticket', 'leave_id', string='Flight Ticket', help="Flight ticket")
    # Commented for odoo 13 compatibility
    # double_validation = fields.Boolean(string='Apply Double Validation', related='holiday_status_id.double_validation')
    expense_account = fields.Many2one('account.account')
    leave_salary = fields.Selection([('0', 'Basic'), ('1', 'Gross')], string='Leave Salary')


    def get_overlapping_leaves(self):
        if self.date_from and self.date_to:
            overlap_leaves = []
            from_date = self.date_from
            to_date = self.date_to
            r = (to_date + timedelta(days=1) - from_date).days
            leave_dates = [str(from_date + timedelta(days=i)) for i in range(r)]
            leaves = self.env['hr.leave'].search([('state', '=', 'validate'),
                                                     ('department_id', '=', self.department_id.id)])
            other_leaves = leaves - self
            for leave in other_leaves:
                frm_dte = leave.date_from
                to_dte = leave.date_to
                r = (to_dte + timedelta(days=1) - frm_dte).days
                leave_dtes = [str(frm_dte + timedelta(days=i)) for i in range(r)]
                if set(leave_dtes).intersection(set(leave_dates)):
                    overlap_leaves.append(leave.id)
            self.update({'overlapping_leaves': [(6, 0, overlap_leaves)]})

    def action_approve(self):
        if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
            raise UserError(_('Only an HR Officer or Manager can approve leave requests.'))

        manager = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
        for holiday in self:
            if holiday.state != 'confirm':
                raise UserError(_('Leave request must be confirmed ("To Approve") in order to approve it.'))

            if holiday.pending_tasks:
                if holiday.user_id:
                    ctx = dict(self.env.context or {})
                    ctx.update({
                        'default_leave_req_id': self.id,
                    })
                    return {
                        'name': _('Re-Assign Task'),
                        'type': 'ir.actions.act_window',
                        'view_mode': 'form',
                        'res_model': 'task.reassign',
                        'target': 'new',
                        'context': ctx,
                    }
            else:
                # if holiday.double_validation:
                #     return holiday.write({'state': 'validate1', 'manager_id': manager.id if manager else False})
                # else:
                holiday.action_validate()

    def book_ticket(self):
        if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
            raise UserError(_('Only an HR Officer or Manager can book flight tickets.'))
        ctx = dict(self.env.context or {})
        ctx.update({
            'default_employee_id': self.employee_id.id,
            'default_leave_id': self.id,
        })
        return {
            'name': _('Book Flight Ticket'),
            'type': 'ir.actions.act_window',
            'view_mode': 'form',
            'view_id': self.env.ref('hr_vacation_mngmt.view_hr_book_flight_ticket_form').id,
            'res_model': 'hr.flight.ticket',
            'target': 'new',
            'context': ctx,
        }

    def get_hr_holiday_managers(self):
        self.holiday_managers = self.env.ref('hr_holidays.group_hr_holidays_manager').users

    def view_flight_ticket(self):
        return {
            'name': _('Flight Ticket'),
            'type': 'ir.actions.act_window',
            'view_mode': 'form',
            'res_model': 'hr.flight.ticket',
            'target': 'current',
            'res_id': self.flight_ticket[0].id,
        }

    @api.model
    def send_leave_reminder(self):
        leave_request = self.env['hr.leave'].search([('state', '=', 'validate')])
        leave_reminder = self.env['ir.config_parameter'].sudo().get_param('leave_reminder')
        reminder_day_before = int(self.env['ir.config_parameter'].sudo().get_param('reminder_day_before'))
        mail_template = self.env.ref('hr_vacation_mngmt.email_template_hr_leave_reminder_mail')
        holiday_managers = self.env.ref('hr_holidays.group_hr_holidays_manager').users
        today = date.today()
        if leave_reminder:
            for request in leave_request:
                if request.date_from:
                    from_date = request.date_from
                    if reminder_day_before == 0:
                        prev_reminder_day = request.date_from
                    else:
                        prev_reminder_day = from_date - timedelta(days=reminder_day_before)
                    if prev_reminder_day == today:
                        for manager in holiday_managers:
                            template = mail_template.sudo().with_context(
                                email_to=manager.email,
                            )
                            template.send_mail(request.id, force_send=True)


class PendingTask(models.Model):
    _name = 'pending.task'

    name = fields.Char(string='Task', required=True)
    leave_id = fields.Many2one('hr.leave', string='Leave Request', help="Leave request")
    dept_id = fields.Many2one('hr.department', string='Department', related='leave_id.department_id', help="Department")
    project_id = fields.Many2one('project.project', string='Project', required=True, help="Project")
    description = fields.Text(string='Description', help="Description")
    assigned_to = fields.Many2one('hr.employee', string='Assigned to', help="Employee who is assigned to",
                                  domain="[('department_id', '=', dept_id)]")
    unavailable_employee = fields.Many2many('hr.employee', string='Unavailable Employees', help="unavailable employee",
                                            compute='get_unavailable_employee')

    def get_unavailable_employee(self):
        unavail_emp = []
        for leave in self.leave_id.overlapping_leaves:
            unavail_emp.append(leave.employee_id.id)
        self.update({'unavailable_employee': unavail_emp})


class HrVacationConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    leave_reminder = fields.Boolean(string='Leave Reminder Email', help="Send leave remainder emails to hr managers")
    reminder_day_before = fields.Integer(string='Reminder Day Before')
    default_expense_account = fields.Many2one('account.account', string='Travel Expense Account', default_model='hr.leave')

    def get_values(self):
        res = super(HrVacationConfigSettings, self).get_values()
        res.update(
            leave_reminder=self.env['ir.config_parameter'].sudo().get_param('leave_reminder'),
            reminder_day_before=int(self.env['ir.config_parameter'].sudo().get_param('reminder_day_before')),
            default_expense_account=int(self.env['ir.config_parameter'].sudo().get_param('travel_expense_account',))
        )
        return res

    def set_values(self):
        super(HrVacationConfigSettings, self).set_values()
        self.env['ir.config_parameter'].sudo().set_param('leave_reminder', self.leave_reminder)
        self.env['ir.config_parameter'].sudo().set_param('reminder_day_before', self.reminder_day_before)
        self.env['ir.config_parameter'].sudo().set_param('travel_expense_account', self.default_expense_account.id)
