# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from datetime import datetime, time

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


class ScopHrTimesheet(models.Model):
    _inherit = "account.analytic.line"

    def _default_ur(self):
        return self.env['res.company']._ur_default_get()

    # Inherited fields
    name = fields.Char(required=False)
    partner_id = fields.Many2one(required=True)
    
    # New fields
    cgscop_timesheet_code_id = fields.Many2one(
        related='project_id.cgscop_timesheet_code_id',
        string='Code Activité National',
        store=True)
    ur_financial_system_id = fields.Many2one(
        comodel_name='ur.financial.system',
        string='Dispositif Financier')
    ur_regional_convention_id = fields.Many2one(
        comodel_name='ur.regional.convention',
        string='Convention Régionale')
    ur_id = fields.Many2one(
        'union.regionale',
        string='Union Régionale',
        index=True,
        ondelete='restrict',
        default=_default_ur)
    sheet_id = fields.Many2one(
        comodel_name='cgscop.timesheet.sheet',
        string="Feuille de temps",
        readonly=True,
        copy=False)
    state = fields.Selection([
        ('to_report', 'A rapporter'),
        ('draft', 'Brouillon'),
        ('submit', 'Soumis'),
        ('valid', 'Validé')],
        compute='_compute_state',
        string='Statut',
        copy=False,
        index=True,
        readonly=True,
        store=True,)
    ur_financial_system_nb = fields.Integer(
        string="Nb Dispositifs Financiers",
        compute="_compute_ur_system_nb")
    ur_regional_convention_nb = fields.Integer(
        string="Nb conventions régionales",
        compute="_compute_ur_system_nb")
    is_present = fields.Boolean("Présentiel")
    justificatifs = fields.Char(
        string="Justificatifs",
        required=False)

    calendar_l1 = fields.Char(
        string='Ligne 1 calendrier',
        compute='_compute_calendar_l1',
        store=False)
    calendar_l2 = fields.Char(
        string='Ligne 2 calendrier',
        compute='_compute_calendar_l2',
        store=False)

    # ------------------------------------------------------
    # Compute Functions
    # ------------------------------------------------------
    @api.depends('ur_id')
    def _compute_ur_system_nb(self):
        for timesheet in self:
            # Calcul nombre de dispositifs financiers
            financial_system = timesheet.env['ur.financial.system'].search([
                ('ur_id', '=', timesheet.ur_id.id)])
            timesheet.ur_financial_system_nb = len(
                financial_system)
            # Calcul nombre de conventions
            regional_convention = timesheet.env['ur.regional.convention'].search([
                ('ur_id', '=', timesheet.ur_id.id)])
            timesheet.ur_regional_convention_nb = len(
                regional_convention)

    @api.depends('sheet_id', 'sheet_id.state')
    def _compute_state(self):
        for timesheet in self:
            if not timesheet.sheet_id:
                timesheet.state = "to_report"
            else:
                timesheet.state = timesheet.sheet_id.state

    @api.depends('project_id', 'partner_id')
    def _compute_calendar_l1(self):
        for ts in self:
            ts.calendar_l1 = ""
            if ts.project_id:
                ts.calendar_l1 += ts.project_id.name + ', '
            if ts.partner_id:
                ts.calendar_l1 += ts.partner_id.name

    @api.depends('unit_amount')
    def _compute_calendar_l2(self):
        for ts in self:
            ts.calendar_l2 = "Durée : " + str(ts.unit_amount) + " heure(s)"

    # ------------------------------------------------------
    # Override le _rec_name
    # ------------------------------------------------------
    @api.multi
    @api.depends('project_id', 'partner_id')
    def name_get(self):
        result = []
        for ts in self:
            name = ts.calendar_l1
            result.append((ts.id, name))
        return result


    # ------------------------------------------------------
    # OnChange Functions
    # ------------------------------------------------------
    @api.onchange('project_id')
    def onchange_project_id(self):
        self.partner_id = self.project_id.partner_id

    @api.onchange('partner_id')
    def onchange_partner_id(self):
        # affiche le Dispositif Financier par défaut sur la LdT
        # si il n'y a pas de date limite du dispositif
        # ou si la date de la Ldt est inférieure à la date limite du dispositif
        if not self.partner_id.ur_financial_system_date or \
           self.date <= self.partner_id.ur_financial_system_date:
            self.ur_financial_system_id = self.partner_id.ur_financial_system_id
        # affiche la Convention par défaut sur la LdT
        # si il n'y a pas de date limite de la convention
        # ou si la date de la LdT est inférieure à la date limite de la convention
        if not self.partner_id.ur_regional_convention_date or \
           self.date <= self.partner_id.ur_regional_convention_date:
            self.ur_regional_convention_id = self.partner_id.\
                ur_regional_convention_id

    # ------------------------------------------------------
    # Contrains
    # ------------------------------------------------------
    @api.constrains('unit_amount')
    def _check_hours(self):
        for record in self:
            lines = self.search([
                ('date', '=', record.date),
                ('employee_id', '=', record.employee_id.id)])
            total = sum(lines.mapped('unit_amount'))
            if (not self.env.user.company_id.day_working
                    and total > self.env.user.company_id.day_duration):
                raise ValidationError(
                    "Vous ne pouvez imputer plus de %sh sur la même journée.\n"
                    "Journée du %s" % (
                        self.env.user.company_id.day_duration,
                        record.date.strftime("%d/%m/%Y")))

    @api.constrains('date')
    def _check_weekday(self):
        for line in self:
            dt = datetime.combine(line.date, time(12, 00))
            holiday = self.env['resource.calendar.leaves'].search([
                '|',
                ('company_id', '=', False),
                ('company_id', '=', self.env.user.company_id.id),
                ('date_from', '<=', dt),
                ('date_to', '>=', dt),
            ])
            if line.date.weekday() in (5, 6) or holiday:
                raise ValidationError(
                    "Vous ne pouvez imputer du temps sur un weekend "
                    "ou un jour férié.")

    # ------------------------------------------------------
    # Override ORM
    # ------------------------------------------------------
    @api.multi
    def unlink(self):
        for timesheet in self:
            if timesheet.state in ['submit', 'valid']:
                raise UserError('Vous ne pouvez pas supprimer une '
                                'ligne de temps soumise ou validée')
        super(ScopHrTimesheet, self).unlink()

    # ------------------------------------------------------
    # Actions
    # ------------------------------------------------------
    @api.multi
    def action_submit_timesheet_lines(self):
        """
            Crée une feuille de temps avec les lignes sélectionnées
        """
        if any(time.state != 'to_report' or time.sheet_id for time in self):
            raise UserError(
                "Vous ne pouvez pas insérer 2 fois la même ligne !")
        if len(self.mapped('employee_id')) != 1:
            raise UserError(
                "Il ne peut y avoir plusieurs employés dans une "
                "même feuille de temps.")

        return {
            'name': 'New Expense Report',
            'type': 'ir.actions.act_window',
            'view_mode': 'form',
            'res_model': 'cgscop.timesheet.sheet',
            'target': 'current',
            'context': {
                'default_timesheet_line_ids': self.ids,
                'default_employee_id': self[0].employee_id.id,
                'default_name': self[0].name if len(self) == 1 else ''
            }
        }