# Copyright 2025 Criptomart
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from datetime import datetime
from datetime import timedelta

from odoo.exceptions import AccessError
from odoo.tests.common import TransactionCase


class TestGroupOrderRecordRules(TransactionCase):
    """Test suite para record rules de multicompañía en group.order."""

    def setUp(self):
        super().setUp()

        # Crear dos compañías
        self.company1 = self.env["res.company"].create(
            {
                "name": "Company 1",
            }
        )
        self.company2 = self.env["res.company"].create(
            {
                "name": "Company 2",
            }
        )

        # Crear usuarios para cada compañía
        self.user_company1 = self.env["res.users"].create(
            {
                "name": "User Company 1",
                "login": "user_c1",
                "password": "pass123",
                "company_id": self.company1.id,
                "company_ids": [(6, 0, [self.company1.id])],
            }
        )

        self.user_company2 = self.env["res.users"].create(
            {
                "name": "User Company 2",
                "login": "user_c2",
                "password": "pass123",
                "company_id": self.company2.id,
                "company_ids": [(6, 0, [self.company2.id])],
            }
        )

        # Crear admin con acceso a ambas compañías
        self.admin_user = self.env["res.users"].create(
            {
                "name": "Admin Both",
                "login": "admin_both",
                "password": "pass123",
                "company_id": self.company1.id,
                "company_ids": [(6, 0, [self.company1.id, self.company2.id])],
            }
        )

        # Crear grupos en cada compañía
        self.group1 = self.env["res.partner"].create(
            {
                "name": "Grupo Company 1",
                "is_company": True,
                "email": "grupo1@test.com",
                "company_id": self.company1.id,
            }
        )

        self.group2 = self.env["res.partner"].create(
            {
                "name": "Grupo Company 2",
                "is_company": True,
                "email": "grupo2@test.com",
                "company_id": self.company2.id,
            }
        )

        # Crear órdenes en cada compañía
        self.order1 = self.env["group.order"].create(
            {
                "name": "Pedido Company 1",
                "group_ids": [(6, 0, [self.group1.id])],
                "company_id": self.company1.id,
                "type": "regular",
                "start_date": datetime.now().date(),
                "end_date": (datetime.now() + timedelta(days=7)).date(),
                "period": "weekly",
                "pickup_day": "5",
                "cutoff_day": "0",
            }
        )

        self.order2 = self.env["group.order"].create(
            {
                "name": "Pedido Company 2",
                "group_ids": [(6, 0, [self.group2.id])],
                "company_id": self.company2.id,
                "type": "regular",
                "start_date": datetime.now().date(),
                "end_date": (datetime.now() + timedelta(days=7)).date(),
                "period": "weekly",
                "pickup_day": "5",
                "cutoff_day": "0",
            }
        )

    def test_user_company1_can_read_own_orders(self):
        """Test que usuario de Company 1 puede leer sus propias órdenes."""
        orders = (
            self.env["group.order"]
            .with_user(self.user_company1)
            .search([("company_id", "=", self.company1.id)])
        )

        self.assertIn(self.order1, orders)

    def test_user_company1_cannot_read_company2_orders(self):
        """Test que usuario de Company 1 NO puede leer órdenes de Company 2."""
        orders = (
            self.env["group.order"]
            .with_user(self.user_company1)
            .search([("company_id", "=", self.company2.id)])
        )

        self.assertNotIn(self.order2, orders)
        self.assertEqual(len(orders), 0)

    def test_admin_can_read_all_orders(self):
        """Test que admin con acceso a ambas compañías ve todas las órdenes."""
        orders = self.env["group.order"].with_user(self.admin_user).search([])

        self.assertIn(self.order1, orders)
        self.assertIn(self.order2, orders)

    def test_user_cannot_write_other_company_order(self):
        """Test que usuario no puede escribir en orden de otra compañía."""
        with self.assertRaises(AccessError):
            self.order2.with_user(self.user_company1).write(
                {
                    "name": "Intentando cambiar nombre",
                }
            )

    def test_record_rule_filters_search(self):
        """Test que búsqueda automáticamente filtra por record rule."""
        # Usuario de Company 1 busca todas las órdenes
        orders_c1 = (
            self.env["group.order"]
            .with_user(self.user_company1)
            .search([("state", "=", "draft")])
        )

        # Solo debe ver su orden
        self.assertEqual(len(orders_c1), 1)
        self.assertEqual(orders_c1[0], self.order1)

    def test_cross_company_access_denied(self):
        """Test que acceso entre compañías es denegado."""
        # Usuario company1 intenta acceder a orden de company2
        with self.assertRaises(AccessError):
            self.order2.with_user(self.user_company1).read()

    def test_admin_can_bypass_company_restriction(self):
        """Test que admin puede acceder a órdenes de cualquier compañía."""
        # Admin lee orden de company2 sin problema
        order2_admin = self.order2.with_user(self.admin_user)
        self.assertEqual(order2_admin.name, "Pedido Company 2")
        self.assertEqual(order2_admin.company_id, self.company2)
