# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2010 Savoir-faire Linux (<http://www.savoirfairelinux.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from odoo import fields, models, api, _


class MgmtSystemAudit(models.Model):
    """Model class that manage audit."""

    _name = "mgmtsystem.audit"
    _description = "Audit"
    _inherit = ['mail.thread']
    name = fields.Char('Name')

    reference = fields.Char(
        'Reference',
        size=64,
        required=True,
        readonly=True,
        default='NEW'
    )
    date = fields.Datetime('Date')
    line_ids = fields.One2many(
        'mgmtsystem.verification.line',
        'audit_id',
        'Verification List',
    )
    number_of_audits = fields.Integer('# of audits', readonly=True, default=1)
    number_of_nonconformities = fields.Integer(
        'Number of nonconformities', readonly=True, store=True,
        compute="_compute_number_of_nonconformities")
    number_of_questions_in_verification_list = fields.Integer(
        'Number of questions in verification list', readonly=True, store=True,
        compute="_compute_number_of_questions_in_verification_list")
    number_of_improvements_opportunity = fields.Integer(
        'Number of improvements Opportunities', readonly=True, store=True,
        compute="_compute_number_of_improvement_opportunities")
    days_since_last_update = fields.Integer(
        'Days since last update', readonly=True, store=True,
        compute="_compute_days_since_last_update")
    closing_date = fields.Datetime('Closing Date', readonly=True)

    number_of_days_to_close = fields.Integer(
        '# of days to close', readonly=True, store=True,
        compute="_compute_number_of_days_to_close")

    user_id = fields.Many2one('res.users', 'Audit Manager')
    auditor_user_ids = fields.Many2many(
        'res.users',
        'mgmtsystem_auditor_user_rel',
        'user_id',
        'mgmtsystem_audit_id',
        'Auditors',
    )
    auditee_user_ids = fields.Many2many(
        'res.users',
        'mgmtsystem_auditee_user_rel',
        'user_id',
        'mgmtsystem_audit_id',
        'Auditees',
    )
    strong_points = fields.Html('Strong Points')
    to_improve_points = fields.Html('Points To Improve')
    imp_opp_ids = fields.Many2many(
        'mgmtsystem.action',
        'mgmtsystem_audit_imp_opp_rel',
        'mgmtsystem_action_id',
        'mgmtsystem_audit_id',
        'Improvement Opportunities',
    )

    nonconformity_ids = fields.Many2many(
        'mgmtsystem.nonconformity',
        string='Nonconformities',
    )
    state = fields.Selection(
        [
            ('open', 'Open'),
            ('done', 'Closed'),
        ],
        'State',
        default="open"
    )
    system_id = fields.Many2one('mgmtsystem.system', 'System')
    company_id = fields.Many2one(
        'res.company', 'Company',
        default=lambda self: self.env.user.company_id.id)

    @api.depends("nonconformity_ids")
    def _compute_number_of_nonconformities(self):
        """Count number of nonconformities."""
        for audit in self:
            audit.number_of_nonconformities = len(self.nonconformity_ids)

    @api.depends("imp_opp_ids")
    def _compute_number_of_improvement_opportunities(self):
        """Count number of improvements Opportunities."""
        for audit in self:
            audit.number_of_improvements_opportunity = len(audit.imp_opp_ids)

    @api.depends("line_ids")
    def _compute_number_of_questions_in_verification_list(self):
        for audit in self:
            audit.number_of_questions_in_verification_list = len(
                audit.line_ids)

    @api.depends("write_date")
    def _compute_days_since_last_update(self):
        for audit in self:
            audit.days_since_last_update = audit._elapsed_days(
                audit.create_date,
                audit.write_date)

    @api.depends("closing_date")
    def _compute_number_of_days_to_close(self):
        for audit in self:
            audit.number_of_days_to_close = audit._elapsed_days(
                audit.create_date,
                audit.closing_date)

    @api.model
    def _elapsed_days(self, dt1_text, dt2_text):
        res = 0
        if dt1_text and dt2_text:
            dt1 = fields.Datetime.from_string(dt1_text)
            dt2 = fields.Datetime.from_string(dt2_text)
            res = (dt2 - dt1).days
        return res

    @api.model
    def create(self, vals):
        """Audit creation."""
        vals.update({
            'reference': self.env['ir.sequence'].next_by_code(
                'mgmtsystem.audit'
            ),
        })
        audit_id = super(MgmtSystemAudit, self).create(vals)
        return audit_id

    @api.multi
    def button_close(self):
        """When Audit is closed, post a message to followers' chatter."""
        self.message_post(_("Audit closed"))
        return self.write({'state': 'done',
                           'closing_date': fields.Datetime.now()})

    def get_action_url(self):
        """
        Return a short link to the audit form view
        eg. http://localhost:8069/?db=prod#id=1&model=mgmtsystem.audit
        """

        base_url = self.env['ir.config_parameter'].get_param(
            'web.base.url',
            default='http://localhost:8069'
        )
        url = ('{}/web#db={}&id={}&model={}').format(
            base_url,
            self.env.cr.dbname,
            self.id,
            self._name
        )
        return url

    def get_lines_by_procedure(self):
        p = []
        for l in self.line_ids:
            if l.procedure_id.id:
                proc_nm = self.pool.get('document.page').read(
                    self.env.cr, self.env.uid, l.procedure_id.id, ['name']
                )
                procedure_name = proc_nm['name']
            else:
                procedure_name = _('Undefined')

            p.append({"id": l.id,
                      "procedure": procedure_name,
                      "name": l.name,
                      "yes_no": "Yes / No"})
        p = sorted(p, key=lambda k: k["procedure"])
        proc_line = False
        q = []
        proc_name = ''
        for i in range(len(p)):
            if proc_name != p[i]['procedure']:
                proc_line = True
            if proc_line:
                q.append({"id": p[i]['id'],
                          "procedure": p[i]['procedure'],
                          "name": "",
                          "yes_no": ""})
                proc_line = False
                proc_name = p[i]['procedure']
            q.append({"id": p[i]['id'],
                      "procedure": "",
                      "name": p[i]['name'],
                      "yes_no": "Yes / No"})
        return q
