# © 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 ValidationError


class ScopPartnerStaff(models.Model):
    _name = "scop.partner.staff"
    _description = "Effectifs"
    _rec_name = "partner_id"
    _order = "effective_date, partner_id"

    # ------------------------------------------------------
    # Default
    # ------------------------------------------------------
    @api.model
    def default_get(self, fields):
        res = super(ScopPartnerStaff, self).default_get(fields)
        partner_id = self.env.context.get("default_partner_id", False)
        if partner_id:
            staff_line = self.search(
                [
                    ("partner_id", "=", partner_id),
                ],
                order="effective_date desc, id desc",
                limit=1,
            )
            if staff_line:
                staff_list = [
                    "staff_count",
                    "staff_shareholder_count",
                    "staff_shareholder_total",
                    "staff_average",
                ]
                for staff in staff_list:
                    res[staff] = staff_line[staff]
        return res

    # ------------------------------------------------------
    # Fields declaration
    # ------------------------------------------------------
    partner_id = fields.Many2one(
        comodel_name="res.partner",
        string="Organisme",
        domain=[("is_cooperative", "=", True)],
        ondelete="restrict",
        required=True,
        index=True,
    )
    partner_city = fields.Char("Ville", related="partner_id.city")
    partner_siret = fields.Char("SIRET", related="partner_id.siret")
    cooperative_form_id = fields.Many2one(related="partner_id.cooperative_form_id")
    naf_id = fields.Many2one(related="partner_id.naf_id")
    is_partner_in_tracked_naf = fields.Boolean(
        "Coop dans les NAF marqués",
        compute="_compute_is_partner_in_tracked_naf",
    )
    user_id = fields.Many2one(
        comodel_name="res.users",
        string="Utilisateur",
        ondelete="restrict",
        required=True,
        default=lambda self: self.env.uid,
    )
    type_entry = fields.Selection(
        [
            ("questionnaire", "Questionnaire"),
            ("questionnaire_inscription", "Questionnaire Inscription"),
            ("membership", "Adhésion"),
            ("regul_ur", "Régularisation UR"),
            ("regul_cg", "Régularisation CG"),
            ("regul_diane", "Régularisation Diane"),
        ],
        string="Type",
        default="regul_ur",
        required=True,
    )
    effective_date = fields.Date(
        string="Date",
        default=lambda self: fields.Date.today(),
        required=True,
    )
    staff_count = fields.Integer(
        "Effectif (EF)",
    )
    staff_shareholder_count = fields.Integer("Nb Sociétaires Salarié")
    staff_shareholder_total = fields.Integer("Total associés")
    staff_average = fields.Float("Equivalent temps plein (ETP)")
    staff_men = fields.Integer("Eff. salariés hommes")
    staff_women = fields.Integer("Eff. salariés femmes")
    staff_shareholder_men = fields.Integer("Sociétaires salariés hommes")
    staff_shareholder_women = fields.Integer("Sociétaires salariés femmes")
    comment = fields.Char("Commentaire")

    is_admin_user = fields.Boolean(
        compute="_compute_is_admin_user",
    )

    # ------------------------------------------------------
    # Compute
    # ------------------------------------------------------
    def _compute_is_partner_in_tracked_naf(self):
        naf_90_01Z = self.env.ref("lefilament_naf.naf_90_01Z").id
        naf_90_02Z = self.env.ref("lefilament_naf.naf_90_02Z").id
        naf_78_20Z = self.env.ref("lefilament_naf.naf_78_20Z").id
        naf_82_11Z = self.env.ref("lefilament_naf.naf_82_11Z").id
        naf_78_10Z = self.env.ref("lefilament_naf.naf_78_10Z").id
        for r in self:
            if r.naf_id.id in (
                naf_90_01Z,
                naf_90_02Z,
                naf_78_20Z,
                naf_82_11Z,
                naf_78_10Z,
            ):
                r.is_partner_in_tracked_naf = True
            else:
                r.is_partner_in_tracked_naf = False

    def _compute_is_admin_user(self):
        self.is_admin_user = (
            self.env.user.has_group("cgscop_partner.group_cg_administrative") or False
        )

    # ------------------------------------------------------
    # OnChange
    # ------------------------------------------------------
    @api.onchange("type_entry")
    def _onchange_type_entry(self):
        """
        Interdit la sélection questionnaire ou questionnaire inscription
        sur l'interface
        """
        if self.type_entry in (
            "questionnaire",
            "questionnaire_inscription",
        ) and not self.env.user.has_group("cgscop_partner.group_cg_administrative"):
            raise ValidationError(
                _('Vous ne pouvez choisir que des types "Régularisation".')
            )

    # ------------------------------------------------------
    # Contrains
    # ------------------------------------------------------
    @api.constrains(
        "cooperative_form_id",
        "type_entry",
        "staff_count",
        "staff_shareholder_count",
        "staff_average",
    )
    def _check_staff(self):
        """
        Règles spécifiques pour les effectifs
        """
        scic = self.env.ref("cgscop_partner.form_scic").id
        scop = self.env.ref("cgscop_partner.form_scop").id

        def check_staff_shareholder():
            # Effectif total >= effectif sociétaires
            if self.staff_shareholder_count > 0:
                if not self.staff_count >= self.staff_shareholder_count:
                    raise ValidationError(
                        _(
                            "L'effectif total doit être supérieur ou égal au "
                            "nombre de sociétaires salariés"
                        )
                    )

        # Les règles ne s'appliquent pas pour les entrées LM / Questionnaire
        if self.type_entry not in ("questionnaire", "questionnaire_inscription"):
            # Règles pour les SCIC
            if self.cooperative_form_id.id == scic:
                check_staff_shareholder()
            # Règles pour les SCOP
            elif self.cooperative_form_id.id == scop:
                # Effectif total non nul
                if self.staff_count == 0:
                    raise ValidationError(
                        _(
                            "L'effectif total doit être supérieur ou égal à 0 "
                            "pour cette copérative de type SCOP"
                        )
                    )
                check_staff_shareholder()

            # Règles sprécifiques pour les NAF suivis
            if self.is_partner_in_tracked_naf:
                if self.staff_average == 0:
                    raise ValidationError(
                        _(
                            "Le nombre d'équivalent temps plein doit être "
                            "renseigné pour cette coopérative"
                        )
                    )

    @api.constrains("effective_date")
    def _check_effective_date(self):
        """
        Interdit la création de deux lignes à une même date
        pour un même partenaire sauf pour LM
        """
        for record in self:
            doublon = self.search(
                [
                    ("partner_id", "=", record.partner_id.id),
                    ("effective_date", "=", record.effective_date),
                ]
            )
            if len(doublon) > 1 and record.type_entry not in (
                "questionnaire",
                "questionnaire_inscription",
            ):
                raise ValidationError(
                    _("Vous ne pouvez pas créer 2 ajustements à la même date.")
                )

    # ------------------------------------------------------
    # Buttons
    # ------------------------------------------------------
    def edit_staff(self):
        form_id = self.env.ref("cgscop_partner.scop_partner_staff_form_view")
        return {
            "type": "ir.actions.act_window",
            "res_model": "scop.partner.staff",
            "view_mode": "form",
            "views": [[form_id.id, "form"]],
            "res_id": self.id,
            "target": "new",
        }