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

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


class ScopHrTimesheetSheet(models.Model):
    _name = "cgscop.timesheet.sheet"
    _inherit = ["mail.thread", "mail.activity.mixin"]
    _description = "Timesheet Report"
    _order = "create_date desc, validation_date desc, id desc"

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

    name = fields.Char("Nom", required=True)
    timesheet_line_ids = fields.One2many(
        comodel_name="account.analytic.line",
        inverse_name="sheet_id",
        string="Lignes de temps",
        states={"valid": [("readonly", True)]},
        copy=False,
    )
    state = fields.Selection(
        [("draft", "Brouillon"), ("submit", "Soumis"), ("valid", "Validé")],
        string="Statut",
        index=True,
        tracking=True,
        copy=False,
        default="draft",
        required=True,
    )
    employee_id = fields.Many2one(
        comodel_name="hr.employee",
        string="Employé",
        required=True,
        readonly=True,
        states={"draft": [("readonly", False)]},
        default=lambda self: self.env["hr.employee"].search(
            [("user_id", "=", self.env.uid)], limit=1
        ),
    )
    total_hour = fields.Float(string="Total", compute="_compute_hour", store=True)
    company_id = fields.Many2one(
        comodel_name="res.company",
        string="Company",
        readonly=True,
        states={"draft": [("readonly", False)]},
        default=lambda self: self.env.company,
    )
    validation_date = fields.Date("Date de validation")
    submit_date = fields.Date("Soumis le")
    ur_id = fields.Many2one(
        "union.regionale",
        string="Union Régionale",
        index=True,
        ondelete="restrict",
        default=_default_ur,
    )
    can_edit = fields.Boolean("Can Reset", compute="_compute_can_reset")

    # ------------------------------------------------------
    # Compute Functions
    # ------------------------------------------------------
    @api.depends("timesheet_line_ids", "timesheet_line_ids.unit_amount")
    def _compute_hour(self):
        for sheet in self:
            sheet.total_hour = sum(sheet.timesheet_line_ids.mapped("unit_amount"))

    def _compute_can_reset(self):
        is_timesheet_user = self.user_has_groups("hr_timesheet.group_timesheet_manager")
        for sheet in self:
            if sheet.state == "draft" or is_timesheet_user:
                sheet.can_edit = True
            else:
                sheet.can_edit = False

    # ------------------------------------------------------
    # Constain Functions
    # ------------------------------------------------------
    @api.constrains("timesheet_line_ids", "employee_id")
    def _check_employee(self):
        for sheet in self:
            employee_ids = sheet.timesheet_line_ids.mapped("employee_id")
            if len(employee_ids) > 1 or (
                len(employee_ids) == 1 and employee_ids != sheet.employee_id
            ):
                raise ValidationError(
                    _(
                        "Vous ne pouvez pas ajouter les lignes"
                        " de temps de plusieurs employés."
                    )
                )

    # ------------------------------------------------------
    # Override ORM
    # ------------------------------------------------------
    def unlink(self):
        for timesheet in self:
            if timesheet.state in ["submit", "valid"]:
                raise UserError(
                    _(
                        "Vous ne pouvez pas supprimer une "
                        "feuille de temps soumise ou validée"
                    )
                )
        super(ScopHrTimesheetSheet, self).unlink()

    # ------------------------------------------------------
    # Action button
    # ------------------------------------------------------
    def action_submit_timesheet(self):
        self.write({"state": "submit", "submit_date": fields.Date.today()})

    def approve_timesheet_sheets(self):
        self.write({"state": "valid", "validation_date": fields.Date.today()})

    def reset_timesheet_sheets(self):
        self.write({"state": "draft", "submit_date": False, "validation_date": False})

    def print_timesheet(self):
        return self.env.ref(
            "cgscop_timesheet.cgscop_timesheet_sheet_report"
        ).report_action(self)

    # ------------------------------------------------------
    # Retourne les lignes de la Fdt avec les totaux par projet
    # ------------------------------------------------------
    def _to_duration(self, infloat):
        return '{0:02.0f}:{1:02.0f}'.format(*divmod(infloat * 60, 60))
    def _get_timesheet_line_act(self):
        for sheet in self:
            lines = sheet.timesheet_line_ids.sorted(key=lambda b: (b.project_id.name, b.date))
            rows = []
            last_project = False
            tot_project = 0
            for line in lines:
                # On insère un total intermédiaire
                if last_project != line.project_id.name and tot_project != 0:
                    rows.append({
                        'total': 1,
                        'name': False,
                        'partner': False,
                        'project': False,
                        'date': False,
                        'ur_financial_system': 'Total ' + last_project + ' : ' + self._to_duration(tot_project),
                        'unit_amount': False,
                    })
                    tot_project = 0

                # On insère la ligne lue
                rows.append({
                    'total': 0,
                    'name': line.name,
                    'partner': line.partner_id.name,
                    'project': line.project_id.name,
                    'date': line.date,
                    'ur_financial_system': line.ur_financial_system_id.name,
                    'unit_amount': self._to_duration(line.unit_amount),
                    })
                last_project = line.project_id.name
                tot_project = tot_project + line.unit_amount

            # On insère le dernier total
            rows.append({
                'total': 1,
                'name': False,
                'partner': False,
                'project': False,
                'date': False,
                'ur_financial_system': 'Total ' + last_project + ' : ' + self._to_duration(tot_project),
                'unit_amount': False,
            })

            return rows