# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime, timedelta

from dateutil.relativedelta import relativedelta
import logging

from odoo import api, fields, models, _
from odoo.exceptions import ValidationError


_logger = logging.getLogger(__name__)


class PlanningShift(models.Model):
    _inherit = 'planning.slot'

    project_id = fields.Many2one('project.project', string="Project", domain="[('company_id', '=', company_id), ('allow_forecast', '=', True)]", check_company=True)
    budgeted_hours = fields.Float("Budgeted hours", default=0, compute='_compute_budgeted_hours', store=True)
    rem_all_hours = fields.Float("Remaining Allocated hours", default=0, compute='_compute_budgeted_hours', store=True)
    task_id = fields.Many2one('project.task', string="Task", domain="[('company_id', '=', company_id), ('project_id', '=', project_id)]", check_company=True)

    _sql_constraints = [
        ('project_required_if_task', "CHECK( (task_id IS NOT NULL AND project_id IS NOT NULL) OR (task_id IS NULL) )", "If the planning is linked to a task, the project must be set too."),
    ]

    @api.model
    def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
        if 'budgeted_hours' in fields:
            fields.remove('budgeted_hours')
        if 'rem_all_hours' in fields:
            fields.remove('rem_all_hours')
        return super(PlanningShift, self).read_group(domain, fields, groupby, offset, limit, orderby, lazy)


    @api.depends('project_id', 'employee_id')
    def _compute_budgeted_hours(self):
        for slot in self:
            if slot.project_id and slot.employee_id:
                if slot.project_id.project_type == 'hours_no_limit':
                    slot.budgeted_hours = slot.project_id.budgeted_hours
                    rec = slot.search([('project_id','=',slot.project_id.id)])
                    all_hours = 0
                    for r in rec:
                        all_hours += r.allocated_hours
                    slot.rem_all_hours = slot.budgeted_hours - all_hours
                if slot.project_id.project_type == 'hours_in_consultant':
                    cons = self.env['project.sale.line.employee.map'].search([('employee_id','=',slot.employee_id.id),('project_id','=',slot.project_id.id)], limit=1)
                    slot.budgeted_hours = cons and cons.budgeted_qty or 0
                    rec = slot.search([('employee_id', '=', slot.employee_id.id),('project_id', '=', slot.project_id.id)])
                    all_hours = 0
                    for r in rec:
                        all_hours += r.allocated_hours
                    slot.rem_all_hours = slot.budgeted_hours - all_hours
                else:
                    slot.budgeted_hours = 0
                    slot.rem_all_hours = 0

    @api.onchange('task_id')
    def _onchange_task_id(self):
        if not self.project_id:
            self.project_id = self.task_id.project_id
        else:
            self.task_id.project_id = self.project_id

    """@api.onchange('employee_id')
    def _onchange_employee_id(self):
        domain = []
        if self.employee_id and not self.employee_id.user_id:
            self.project_id = False
            domain = [('id', 'in', [])]
        if self.employee_id:
            self.project_id = False
            domain = [('id', 'in', [])]
        if self.employee_id and self.employee_id.user_id:
            manager_id = self.env['project.project'].search(
                [('user_id', '=', self.employee_id.user_id.id), ('allow_forecast', '=', True)]).ids
            emp_project_ids = self.env['project.project'].search(
                [('privacy_visibility', 'in', ('employees', 'portal')), ('allow_forecast', '=', True)]).ids
            project_ids = self.env['project.project'].search(
                [('privacy_visibility', '=', 'followers'), ('allow_forecast', '=', True),
                 ('allowed_internal_user_ids', 'in', self.employee_id.user_id.id)]).ids
            consul_ids = self.env['project.sale.line.employee.map'].search([('employee_id', '=', self.employee_id.id)])
            consul_project_ids = [val.project_id.id  for val in consul_ids]
            emp_all_project_ids = manager_id + emp_project_ids + project_ids + consul_project_ids
            domain = [('id', 'in', list(set(emp_all_project_ids)))]
        result = {
            'domain': {'project_id': domain},
        }
        return result"""

    @api.onchange('project_id')
    def _onchange_project_id(self):
        domain = [] if not self.project_id else [('project_id', '=', self.project_id.id)]
        manager_id = []
        user_ids = []
        consul_project_ids = []
        if self.project_id:
            consul_ids = self.env['project.sale.line.employee.map'].search([('project_id', '=', self.project_id.id)])
            consul_project_ids = [val.employee_id.id for val in consul_ids]
        if self.project_id and self.project_id.user_id:
            manager_id = self.env['hr.employee'].search([('user_id', '=', self.project_id.user_id.id)]).ids
        if self.project_id and self.project_id.privacy_visibility in ('employees', 'portal'):
            user_ids = self.env['hr.employee'].search([('user_id', '!=', False)]).ids
        if self.project_id and self.project_id.privacy_visibility == 'followers':
            user_ids = self.env['hr.employee'].search([('user_id', 'in', self.project_id.allowed_internal_user_ids.ids)]).ids
        project_all_emp_ids = manager_id + user_ids + consul_project_ids
        result = {
            'domain': {'task_id': domain, 'employee_id': [('id', 'in', project_all_emp_ids)]},
        }
        if self.project_id != self.task_id.project_id:
            # reset task when changing project
            self.task_id = False
        return result

    @api.constrains('task_id', 'project_id')
    def _check_task_in_project(self):
        for forecast in self:
            if forecast.task_id and (forecast.task_id not in forecast.project_id.tasks):
                raise ValidationError(_("Your task is not in the selected project."))

    def _read_group_project_id(self, projects, domain, order):
        if self._context.get('planning_expand_project'):
            return self.env['planning.slot'].search([('create_date', '>', datetime.now() - timedelta(days=30))]).mapped('project_id')
        return projects

    def _get_fields_breaking_publication(self):
        """ Fields list triggering the `publication_warning` to True when updating shifts """
        result = super(PlanningShift, self)._get_fields_breaking_publication()
        result.extend(['project_id', 'task_id'])
        return result
