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

from odoo import models, fields, api
from math import ceil

class TimerMixin(models.AbstractModel):
    _name = 'timer.mixin'
    _description = 'Timer Mixin'

    timer_start = fields.Datetime(related='user_timer_id.timer_start')
    timer_pause = fields.Datetime(related='user_timer_id.timer_pause')
    is_timer_running = fields.Boolean(related='user_timer_id.is_timer_running')
    user_timer_id = fields.One2many('timer.timer', compute='_compute_user_timer_id', search='_search_user_timer_id')

    display_timer_start_primary = fields.Boolean(compute='_compute_display_timer_buttons')
    display_timer_stop = fields.Boolean(compute='_compute_display_timer_buttons')
    display_timer_pause = fields.Boolean(compute='_compute_display_timer_buttons')
    display_timer_resume = fields.Boolean(compute='_compute_display_timer_buttons')

    def _search_user_timer_id(self, operator, value):
        timers = self.env['timer.timer'].search([
            ('id', operator, value),
            ('user_id', '=', self.env.user.id),
        ])
        return [('id', 'in', timers.mapped('res_id'))]

    @api.depends_context('uid')
    def _compute_user_timer_id(self):
        """ Get the timers according these conditions
            :user_id is is the current user
            :res_id is the current record
            :res_model is the current model
            limit=1 by security but the search should never have more than one record
        """
        for record in self:
            record.user_timer_id = self.env['timer.timer'].search([
                ('user_id', '=', record.env.user.id),
                ('res_id', '=', record.id),
                ('res_model', '=', record._name)
            ], limit=1)

    @api.model
    def _get_user_timers(self):
        # Return user's timers. Can have multiple timers if some are in pause
        return self.env['timer.timer'].search([('user_id', '=', self.env.user.id)])

    def action_timer_start(self):
        """ Start the timer of the current record
        First, if a timer is running, stop or pause it
        If there isn't a timer for the current record, create one then start it
        Otherwise, resume or start it
        """
        self.ensure_one()
        self._stop_timer_in_progress()
        timer = self.user_timer_id
        if not timer:
            timer = self.env['timer.timer'].create({
                'timer_start' : False,
                'timer_pause' : False,
                'is_timer_running' : False,
                'res_model' : self._name,
                'res_id' : self.id,
                'user_id' : self.env.user.id,
            })
            timer.action_timer_start()
        else:
            # Check if it is in pause then resume it or start it
            if timer.timer_pause:
                timer.action_timer_resume()
            else:
                timer.action_timer_start()

    def action_timer_stop(self):
        """ Stop the timer of the current record
        Unlink the timer, it's useless to keep the stopped timer.
        A new timer can be create if needed
        Return the amount of minutes spent
        """
        self.ensure_one()
        timer = self.user_timer_id
        minutes_spent = timer.action_timer_stop()
        timer.unlink()
        return minutes_spent

    def action_timer_pause(self):
        self.ensure_one()
        timer = self.user_timer_id
        timer.action_timer_pause()

    def action_timer_resume(self):
        self.ensure_one()
        self._stop_timer_in_progress()
        timer = self.user_timer_id
        timer.action_timer_resume()

    def _action_interrupt_user_timers(self):
        # Interruption is the action called when the timer is stoped by the start of another one
        self.action_timer_pause()

    def _stop_timer_in_progress(self):
        """
        Cancel the timer in progress if there is one
        Each model can interrupt the running timer in a specific way
        By setting it in pause or stop by example
        """
        timer = self._get_user_timers().filtered(lambda t: t.is_timer_running)
        if timer:
            model = self.env[timer.res_model].browse(timer.res_id)
            model._action_interrupt_user_timers()

    @api.depends('timer_start', 'timer_pause')
    def _compute_display_timer_buttons(self):
        for record in self:
            start_p, stop, pause, resume = True, True, True, True
            if record.timer_start:
                start_p = False
                if record.timer_pause:
                    pause = False
                else:
                    resume = False
            record.write({
                'display_timer_start_primary': start_p,
                'display_timer_stop': stop,
                'display_timer_pause': pause,
                'display_timer_resume': resume,
            })
            return {'start_p': start_p, 'stop': stop, 'pause': pause, 'resume': resume}

    @api.model
    def _timer_rounding(self, minutes_spent, minimum, rounding):
        minutes_spent = max(minimum, minutes_spent)
        if rounding and ceil(minutes_spent % rounding) != 0:
            minutes_spent = ceil(minutes_spent / rounding) * rounding
        return minutes_spent
