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

"""Tests for home_delivery auto-computation on group.order.

Covers:
- group.order.home_delivery derives from delivery_product_id
- Recomputes correctly when product is set/cleared
- sale.order.home_delivery is set when effective delivery is requested
- _get_effective_delivery_context honours the computed flag
"""

from datetime import timedelta

from odoo import fields
from odoo.tests.common import TransactionCase

from ..controllers.website_sale import AplicoopWebsiteSale


class TestHomeDeliveryCompute(TransactionCase):
    """Unit tests for group.order.home_delivery computed field."""

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

        self.group = self.env["res.partner"].create(
            {
                "name": "Delivery Test Group",
                "is_company": True,
                "is_group": True,
            }
        )

        self.delivery_product = self.env["product.product"].create(
            {
                "name": "Home Delivery Service",
                "type": "service",
                "list_price": 3.5,
            }
        )

        self._base_vals = {
            "name": "Delivery Test Order",
            "group_ids": [(6, 0, [self.group.id])],
            "type": "regular",
            "period": "weekly",
            "pickup_day": "3",
            "cutoff_day": "1",
            "start_date": fields.Date.today(),
            "end_date": fields.Date.today() + timedelta(days=14),
        }

    def _make_group_order(self, **extra):
        vals = dict(self._base_vals, **extra)
        return self.env["group.order"].create(vals)

    # --- compute correctness ---

    def test_home_delivery_true_when_product_set(self):
        order = self._make_group_order(delivery_product_id=self.delivery_product.id)
        self.assertTrue(
            order.home_delivery,
            "home_delivery should be True when delivery_product_id is set",
        )

    def test_home_delivery_false_without_product(self):
        order = self._make_group_order()
        self.assertFalse(
            order.home_delivery,
            "home_delivery should be False when no delivery_product_id",
        )

    def test_home_delivery_recomputes_when_product_set(self):
        order = self._make_group_order()
        self.assertFalse(order.home_delivery)

        order.delivery_product_id = self.delivery_product.id
        self.assertTrue(
            order.home_delivery,
            "home_delivery should recompute to True after setting delivery_product_id",
        )

    def test_home_delivery_recomputes_when_product_cleared(self):
        order = self._make_group_order(delivery_product_id=self.delivery_product.id)
        self.assertTrue(order.home_delivery)

        order.delivery_product_id = False
        self.assertFalse(
            order.home_delivery,
            "home_delivery should recompute to False after clearing delivery_product_id",
        )

    def test_direct_write_to_home_delivery_is_overridden_by_compute(self):
        """Writing home_delivery directly must not stick — compute wins."""
        order = self._make_group_order()
        # Attempt to set home_delivery=True without a product
        order.home_delivery = True
        order.invalidate_recordset()
        self.assertFalse(
            order.home_delivery,
            "Computed field must override any direct write without a delivery product",
        )


class TestHomeDeliveryEffectiveContext(TransactionCase):
    """Tests for _get_effective_delivery_context and sale.order.home_delivery."""

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

        self.group = self.env["res.partner"].create(
            {
                "name": "Ctx Test Group",
                "is_company": True,
                "is_group": True,
            }
        )
        self.member_partner = self.env["res.partner"].create(
            {"name": "Ctx Member", "email": "ctx@test.com"}
        )
        self.group.member_ids = [(4, self.member_partner.id)]

        self.user = self.env["res.users"].create(
            {
                "name": "Ctx User",
                "login": "ctx_user@test.com",
                "email": "ctx_user@test.com",
                "partner_id": self.member_partner.id,
            }
        )

        self.delivery_product = self.env["product.product"].create(
            {"name": "Delivery Svc", "type": "service", "list_price": 2.0}
        )

        today = fields.Date.today()
        self.group_order_with_delivery = self.env["group.order"].create(
            {
                "name": "GO With Delivery",
                "group_ids": [(6, 0, [self.group.id])],
                "type": "regular",
                "period": "weekly",
                "pickup_day": "4",
                "cutoff_day": "1",
                "start_date": today,
                "end_date": today + timedelta(days=14),
                "delivery_product_id": self.delivery_product.id,
            }
        )
        self.group_order_with_delivery.action_open()

        self.group_order_no_delivery = self.env["group.order"].create(
            {
                "name": "GO No Delivery",
                "group_ids": [(6, 0, [self.group.id])],
                "type": "regular",
                "period": "weekly",
                "pickup_day": "4",
                "cutoff_day": "1",
                "start_date": today,
                "end_date": today + timedelta(days=14),
            }
        )
        self.group_order_no_delivery.action_open()

        self.controller = AplicoopWebsiteSale()

    # --- _get_effective_delivery_context ---

    def test_delivery_enabled_when_product_configured_and_requested(self):
        effective, _ = self.controller._get_effective_delivery_context(
            self.group_order_with_delivery, is_delivery=True
        )
        self.assertTrue(
            effective,
            "Delivery should be effective when group order has delivery product and user requests it",
        )

    def test_delivery_disabled_when_product_configured_but_not_requested(self):
        effective, _ = self.controller._get_effective_delivery_context(
            self.group_order_with_delivery, is_delivery=False
        )
        self.assertFalse(
            effective,
            "Delivery should not be effective when user did not request it",
        )

    def test_delivery_disabled_when_no_product_even_if_requested(self):
        effective, _ = self.controller._get_effective_delivery_context(
            self.group_order_no_delivery, is_delivery=True
        )
        self.assertFalse(
            effective,
            "Delivery should not be effective when group order has no delivery product",
        )

    # --- sale.order.home_delivery propagation ---

    def test_sale_order_home_delivery_set_when_delivery_requested(self):
        """sale.order.home_delivery must be True when group order has product and user requests delivery."""
        order_vals = {
            "partner_id": self.member_partner.id,
            "group_order_id": self.group_order_with_delivery.id,
            "pickup_day": self.group_order_with_delivery.pickup_day,
            "pickup_date": self.group_order_with_delivery.pickup_date,
            "home_delivery": True,
            "order_line": [],
            "state": "draft",
        }
        sale_order = self.env["sale.order"].sudo().create(order_vals)
        self.assertTrue(
            sale_order.home_delivery,
            "sale.order.home_delivery should be True when group order has delivery enabled",
        )

    def test_sale_order_home_delivery_false_without_group_order_product(self):
        """sale.order.home_delivery must be False when group order has no delivery product."""
        order_vals = {
            "partner_id": self.member_partner.id,
            "group_order_id": self.group_order_no_delivery.id,
            "pickup_day": self.group_order_no_delivery.pickup_day,
            "pickup_date": self.group_order_no_delivery.pickup_date,
            "home_delivery": self.group_order_no_delivery.home_delivery,
            "order_line": [],
            "state": "draft",
        }
        sale_order = self.env["sale.order"].sudo().create(order_vals)
        self.assertFalse(
            sale_order.home_delivery,
            "sale.order.home_delivery should be False when group order has no delivery product",
        )
