# © 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 "{:02.0f}:{: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