"""Idempotent seed data for the B2B ordering portal.

Creates a small demo catalogue, a demo ordering customer + buyer user, a price
list, and a customer-specific price so the acceptance-criteria flow works
out of the box. Safe to run on every startup — it no-ops once seeded.
"""
from __future__ import annotations

import logging

from sqlalchemy import select
from sqlalchemy.orm import Session

from app.core.config import settings
from app.models.client_access import ClientAccount, ClientFeatureAccess, ClientUser
from app.models.ordering import (
    CatalogueProduct,
    CustomerPriceAssignment,
    CustomerProductPrice,
    NotificationSetting,
    PriceList,
    PriceListItem,
    ProductCategory,
)
from app.services.client_access_service import (
    MODULE_INDEX,
    ensure_user_module_permissions,
)

logger = logging.getLogger("data_entry_app.seed")

ORDERING_TENANT = settings.client_tenant_id

_CATEGORIES = [
    ("grains", "Grains", 10),
    ("premixed", "Premixed Products", 20),
    ("bags", "Bags", 30),
    ("bulk_loads", "Bulk Loads", 40),
    ("custom_blends", "Custom Blends", 50),
    ("services", "Services & Delivery", 60),
]

_PRODUCTS = [
    # (name, sku, category, uom, unit_size, moq, base_price, stock, requires_quote)
    ("Cracked Maize", "GRN-MAIZE-20", "grains", "20kg bag", "20kg", 1, 24.50, "in_stock", False),
    ("Whole Barley", "GRN-BARLEY-20", "grains", "20kg bag", "20kg", 1, 21.00, "in_stock", False),
    ("Layer Premix", "PMX-LAYER-20", "premixed", "20kg bag", "20kg", 1, 32.75, "in_stock", False),
    ("Calf Starter Premix", "PMX-CALF-20", "premixed", "20kg bag", "20kg", 5, 38.40, "low_stock", False),
    ("Bulka Bag (1T)", "BAG-BULKA-1T", "bags", "each", "1 tonne", 1, 9.50, "in_stock", False),
    ("Bulk Maize Load", "BLK-MAIZE-T", "bulk_loads", "tonne", "per tonne", 1, 685.00, "made_to_order", False),
    ("Custom Horse Blend", "CST-HORSE-20", "custom_blends", "20kg bag", "20kg", 10, None, "made_to_order", True),
    ("Delivery (per pallet)", "SVC-DELIVERY", "services", "pallet", "1 pallet", 1, 45.00, "in_stock", False),
]


def seed_ordering(db: Session) -> dict[str, int]:
    created = {"categories": 0, "products": 0, "customer": 0, "pricing": 0}

    # Categories
    existing_categories = {
        c.slug for c in db.scalars(select(ProductCategory).where(ProductCategory.tenant_id == ORDERING_TENANT)).all()
    }
    for slug, name, sort_order in _CATEGORIES:
        if slug in existing_categories:
            continue
        db.add(ProductCategory(tenant_id=ORDERING_TENANT, slug=slug, name=name, sort_order=sort_order))
        created["categories"] += 1

    # Catalogue products
    existing_skus = {
        p.sku for p in db.scalars(select(CatalogueProduct).where(CatalogueProduct.tenant_id == ORDERING_TENANT)).all()
    }
    product_by_sku: dict[str, CatalogueProduct] = {}
    for name, sku, category, uom, unit_size, moq, base_price, stock, requires_quote in _PRODUCTS:
        if sku in existing_skus:
            continue
        product = CatalogueProduct(
            tenant_id=ORDERING_TENANT,
            name=name,
            sku=sku,
            category=category,
            unit_of_measure=uom,
            unit_size=unit_size,
            min_order_quantity=moq,
            base_price=base_price,
            stock_status=stock,
            requires_quote=requires_quote,
        )
        db.add(product)
        product_by_sku[sku] = product
        created["products"] += 1
    db.flush()

    # Notification settings row
    if db.scalar(select(NotificationSetting).where(NotificationSetting.tenant_id == ORDERING_TENANT)) is None:
        db.add(
            NotificationSetting(
                tenant_id=ORDERING_TENANT,
                internal_recipients=settings.admin_email,
                send_customer_confirmation=True,
                require_po_number=False,
                from_email=settings.admin_email,
            )
        )

    # Demo ordering customer + buyer user
    demo = db.scalar(select(ClientAccount).where(ClientAccount.client_code == "RIVERSIDE"))
    if demo is None:
        demo = ClientAccount(
            tenant_id="riverside-stockfeeds",
            name="Riverside Stockfeeds",
            client_code="RIVERSIDE",
            status="active",
            notes="Demo B2B ordering customer",
        )
        db.add(demo)
        db.flush()
        created["customer"] += 1

        info = MODULE_INDEX["ordering"]
        db.add(
            ClientFeatureAccess(
                tenant_id=demo.tenant_id,
                client_account_id=demo.id,
                feature_key="ordering",
                feature_name=info["module_name"],
                feature_group=info["module_group"],
                description=info["description"],
                enabled=True,
            )
        )
        buyer = ClientUser(
            tenant_id=demo.tenant_id,
            client_account_id=demo.id,
            full_name="Riverside Buyer",
            email="buyer@riverside.example",
            role="buyer",
            status="active",
            is_new_user=False,
        )
        db.add(buyer)
        db.flush()
        ensure_user_module_permissions(db, buyer)

        # A customer-specific contract price + a small discount on the rest.
        maize = db.scalar(
            select(CatalogueProduct).where(
                CatalogueProduct.tenant_id == ORDERING_TENANT, CatalogueProduct.sku == "GRN-MAIZE-20"
            )
        )
        if maize is not None:
            db.add(
                CustomerProductPrice(
                    tenant_id=ORDERING_TENANT,
                    client_account_id=demo.id,
                    product_id=maize.id,
                    unit_price=22.00,
                    rule_type="contract",
                    contract_reference="2026 supply agreement",
                )
            )
        db.add(
            CustomerPriceAssignment(
                tenant_id=ORDERING_TENANT,
                client_account_id=demo.id,
                price_list_id=None,
                discount_percent=5.0,
            )
        )
        created["pricing"] += 1

    return created
