# 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 ValidationError
from odoo.tests.common import TransactionCase


class TestMultiCompanyGroupOrder(TransactionCase):
    """Test suite para el soporte multicompañía en group.order."""

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

        # Crear dos compañías
        company_model = self.env["res.company"]

        # Compatibilidad con esquemas legacy: columna NOT NULL presente sin campo ORM.
        self.env.cr.execute("""
            SELECT column_name
            FROM information_schema.columns
            WHERE table_name = 'res_company'
              AND column_name IN ('batch_summary_restriction_scope', 'batch_detailed_restriction_scope')
            """)
        existing_columns = {row[0] for row in self.env.cr.fetchall()}
        if (
            "batch_summary_restriction_scope" in existing_columns
            and "batch_summary_restriction_scope" not in company_model._fields
        ):
            self.env.cr.execute(
                "ALTER TABLE res_company ALTER COLUMN batch_summary_restriction_scope SET DEFAULT 'processed'"
            )
        if (
            "batch_detailed_restriction_scope" in existing_columns
            and "batch_detailed_restriction_scope" not in company_model._fields
        ):
            self.env.cr.execute(
                "ALTER TABLE res_company ALTER COLUMN batch_detailed_restriction_scope SET DEFAULT 'processed'"
            )

        def _company_vals(name):
            vals = {"name": name}
            if "batch_summary_restriction_scope" in company_model._fields:
                vals["batch_summary_restriction_scope"] = "processed"
            if "batch_detailed_restriction_scope" in company_model._fields:
                vals["batch_detailed_restriction_scope"] = "processed"
            return vals

        self.company1 = company_model.create(_company_vals("Company 1"))
        self.company2 = company_model.create(_company_vals("Company 2"))

        # Crear grupos en diferentes compañías
        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 productos en cada compañía
        self.product1 = self.env["product.product"].create(
            {
                "name": "Producto Company 1",
                "type": "consu",
                "list_price": 10.0,
                "company_id": self.company1.id,
            }
        )

        self.product2 = self.env["product.product"].create(
            {
                "name": "Producto Company 2",
                "type": "consu",
                "list_price": 20.0,
                "company_id": self.company2.id,
            }
        )

    def test_group_order_has_company_id(self):
        """Test que group.order tenga el campo company_id."""
        order = 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.assertTrue(order.exists())
        self.assertEqual(order.company_id, self.company1)

    def test_group_order_default_company(self):
        """Test que company_id por defecto sea la compañía del usuario."""
        # Crear usuario con compañía específica
        user = self.env["res.users"].create(
            {
                "name": "Test User",
                "login": "testuser",
                "password": "test123",
                "company_id": self.company1.id,
                "company_ids": [(6, 0, [self.company1.id])],
            }
        )

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

        # Verificar que se asignó la compañía del usuario
        self.assertEqual(order.company_id, self.company1)

    def test_group_order_company_constraint(self):
        """Test que solo grupos de la misma compañía se puedan asignar."""
        # Intentar asignar un grupo de otra compañía
        with self.assertRaises(ValidationError):
            self.env["group.order"].create(
                {
                    "name": "Pedido Mixed Companies",
                    "group_ids": [(6, 0, [self.group1.id, self.group2.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",
                }
            )

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

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

        # Obtener órdenes activas de company1
        active_orders = (
            self.env["group.order"]
            .with_context(allowed_company_ids=[self.company1.id])
            .get_active_orders_for_week()
        )

        # Debería contener solo order1
        self.assertIn(order1, active_orders)
        # order2 podría no estar en el resultado si se implementa
        # el filtro de compañía correctamente

    def test_product_company_isolation(self):
        """Test que los productos de diferentes compañías estén aislados."""
        # Crear categoría para products
        category = self.env["product.category"].create(
            {
                "name": "Test Category",
            }
        )

        order = self.env["group.order"].create(
            {
                "name": "Pedido con Categoría",
                "group_ids": [(6, 0, [self.group1.id])],
                "category_ids": [(6, 0, [category.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.assertTrue(order.exists())
        self.assertEqual(order.company_id, self.company1)
        self.assertIn(category, order.category_ids)
