# Copyright 2015 Camptocamp SA - Guewen Baconnier
# Copyright 2017 Tecnativa, S.L. - Luis M. Ontalba
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from datetime import timedelta

from odoo import _, api, exceptions, fields, models
from odoo.tools.float_utils import float_compare


class AccountAnalyticLine(models.Model):
    _inherit = "account.analytic.line"
    _order = "date desc, time_start desc, id desc"

    time_start = fields.Float(string="Begin Hour")
    time_stop = fields.Float(string="End Hour")

    @api.constrains("time_start", "time_stop", "unit_amount")
    def _check_time_start_stop(self):
        for line in self:
            value_to_html = self.env["ir.qweb.field.float_time"].value_to_html
            start = timedelta(hours=line.time_start)
            stop = timedelta(hours=line.time_stop)
            if stop < start:
                value_to_html(line.time_start, None)
                value_to_html(line.time_stop, None)

                raise exceptions.ValidationError(
                    _(
                        "The beginning hour (%(html_start)s) must "
                        "precede the ending hour (%(html_stop)s)."
                    )
                    % {
                        "html_start": value_to_html(line.time_start, None),
                        "html_stop": value_to_html(line.time_stop, None),
                    }
                )
            hours = (stop - start).seconds / 3600
            rounding = self.env.ref("uom.product_uom_hour").rounding
            if hours and float_compare(
                hours, line.unit_amount, precision_rounding=rounding
            ):
                raise exceptions.ValidationError(
                    _(
                        "The duration (%(html_unit_amount)s) must be equal to the difference "
                        "between the hours (%(html_hours)s)."
                    )
                    % {
                        "html_unit_amount": value_to_html(line.unit_amount, None),
                        "html_hours": value_to_html(hours, None),
                    }
                )
            # check if lines overlap
            others = self.search(
                [
                    ("id", "!=", line.id),
                    ("employee_id", "=", line.employee_id.id),
                    ("date", "=", line.date),
                    ("time_start", "<", line.time_stop),
                    ("time_stop", ">", line.time_start),
                ]
            )
            if others:
                message = _("Lines can't overlap:\n")
                message += "\n".join(
                    [
                        "%s - %s"
                        % (
                            value_to_html(other.time_start, None),
                            value_to_html(other.time_stop, None),
                        )
                        for other in (line + others).sorted(lambda l: l.time_start)
                    ]
                )
                raise exceptions.ValidationError(message)

    @api.onchange("time_start", "time_stop")
    def onchange_hours_start_stop(self):
        start = timedelta(hours=self.time_start)
        stop = timedelta(hours=self.time_stop)
        if stop < start:
            return
        self.unit_amount = (stop - start).seconds / 3600

    def merge_timesheets(self):  # pragma: no cover
        """This method is needed in case hr_timesheet_sheet is installed"""
        lines = self.filtered(lambda l: not l.time_start and not l.time_stop)
        if lines:
            return super(AccountAnalyticLine, lines).merge_timesheets()
        return self[0]
