from odoo import api, fields, models, _
from odoo.exceptions import UserError, AccessError, ValidationError
from datetime import datetime, timedelta
from dateutil import relativedelta


class ProjectResourceWizard(models.TransientModel):
    _name = 'project.resource.wizard'

    @api.model
    def default_get(self, fields):
        res = super(ProjectResourceWizard, self).default_get(fields)
        res_id = self._context.get('active_id')
        record = self.env['project.project'].browse(res_id)
        lines = []
        emp_id = []
        for rec in record.sale_line_employee_ids:
            resource_rec = {}
            if rec.employee_id and rec.employee_id.id not in emp_id:
                emp_id.append(rec.employee_id.id)
                resource_rec.update({'employee_id': rec.employee_id.id, 'project_id': res_id,
                                     'employee_price': rec.employee_id.timesheet_cost})
                lines.append((0, 0, resource_rec))
        res.update({'add_project_resource': lines})
        return res

    project_id = fields.Many2one('project.project')
    add_project_resource = fields.One2many('project.resource.line', 'wizard_id')

    def action_add_project_lines(self):
        record = self.env['project.sale.line.employee.map']
        for val in self.add_project_resource:
            ############# Here we check all start date should be filled
            if any([val.start_date is False]):
                raise ValidationError("Please Select Start Date For Every Resource")
            #############
            #################
            if self.project_id.sale_line_employee_ids:
                for emp in self.project_id.sale_line_employee_ids:
                    if emp.employee_id == val.employee_id and emp.end_date == False and val.start_date:
                        emp.write({'end_date': val.start_date - relativedelta.relativedelta(days=1)})
            #################
            values = {
                'project_id': self.project_id.id,
                'employee_id': val.employee_id.id,
                'role': val.role,
                'start_date': val.start_date,
                'end_date': val.end_date,
                'price_unit': val.price_unit,
                'budgeted_qty': val.budgeted_qty,
                'cost': val.cost,
                'employee_price': val.employee_price,
            }
            if self.project_id.hour_distribution == 'Percentage':
                values.update({'distribution_per': val.distribution_per})
            record.create(values)
        return True


class ProjectResourceLine(models.Model):
    _name = "project.resource.line"
    _description = "Project Resource Line"

    wizard_id = fields.Integer()
    project_id = fields.Many2one('project.project')
    employee_id = fields.Many2one('hr.employee')
    employee_ids = fields.Many2many('hr.employee', compute='_compute_allow_employee_ids')
    role = fields.Selection([('Manager', 'Manager'), ('Employee', 'Employee'), ], string="Role", default="Employee")
    start_date = fields.Date()
    end_date = fields.Date()
    price_unit = fields.Float("Hourly Rate")
    budgeted_qty = fields.Float(string='Bud. Hours', digits=(16, 2))
    cost = fields.Float("Bud. Revenue", default=0.0)
    employee_price = fields.Float(string="Cons. Price")
    hour_distribution = fields.Selection(related='project_id.hour_distribution')
    distribution_per = fields.Float("%")

    @api.depends('employee_id')
    def _compute_allow_employee_ids(self):
        for rec in self:
            if rec.project_id.privacy_visibility == 'followers':
                users = rec.project_id.allowed_internal_user_ids
                employees = self.env['hr.employee'].search([('user_id', 'in', users.ids)]).ids
            elif rec.project_id.privacy_visibility == 'employees':
                employees = self.env['hr.employee'].search([]).ids
            else:
                portal_users = rec.project_id.allowed_portal_user_ids
                employees = self.env['hr.employee'].search([]).ids + portal_users.ids
            rec.employee_ids = employees

    @api.onchange('employee_id')
    def onchange_employee_price(self):
        if self.employee_id:
            self.employee_price = self.employee_id.timesheet_cost
        else:
            self.employee_price = 0.0

    @api.onchange('price_unit', 'budgeted_qty')
    def _calculate_total_cost(self):
        if self.project_id.project_type == 'hours_in_consultant':
            if self.hour_distribution == 'Manual':
                self.cost = self.price_unit * self.budgeted_qty

    @api.onchange('price_unit', 'distribution_per', 'employee_id', 'role', 'budgeted_qty')
    def _compute_total_cost(self):
        for val in self:
            if val.project_id.project_type == 'hours_in_consultant':
                if val.hour_distribution == 'Percentage':
                    if val.role == 'Manager':
                        val.cost = val.project_id.budgeted_revenue * (val.project_id.manager_per / 100) * (
                                val.distribution_per / 100)
                    else:
                        val.cost = val.project_id.budgeted_revenue * (val.project_id.employee_per / 100) * (
                                val.distribution_per / 100)
                    if val.price_unit > 0.0:
                        val.budgeted_qty = val.cost / val.price_unit

    @api.onchange('start_date', 'end_date')
    def _onchange_start_end_date(self):
        # if self.start_date:
        #     self.end_date = self.start_date + relativedelta.relativedelta(months=1) - relativedelta.relativedelta(days=1)
        if self.start_date and self.end_date and (self.start_date > self.end_date):
            raise AccessError('End date could not be greater than start date')
        if self.project_id:
            if self.start_date and not self.project_id.date_start <= self.start_date <= self.project_id.date:
                raise AccessError(_('Allocation Start date must be between %s to %s') % (
                self.project_id.date_start.strftime('%d-%b-%Y'), self.project_id.date.strftime('%d-%b-%Y')))
            if self.end_date and not (self.project_id.date_start <= self.end_date <= self.project_id.date):
                raise AccessError(_('Allocation Start date must be between %s to %s') % (
                self.project_id.date_start.strftime('%d-%b-%Y'), self.project_id.date.strftime('%d-%b-%Y')))
