"""Seed SME-Hub marketplace (SP3b) demo data.

Idempotent. Builds on SP1 onboarding (verified entrepreneurs + businesses).

Produces approximately:
* 15 verified buyer registry entries
* 25 product listings (mix of draft / published)
* 8 market demand listings
* ~16 demand responses across statuses
"""
from __future__ import annotations

import logging
import random
from datetime import timedelta

from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import make_password
from django.db import transaction
from django.utils import timezone

from apps.core.countries import to_country_name
from apps.core.permissions.roles import UserRole
from apps.smehub.marketplace.models import (
    BuyerRegistryEntry,
    DemandResponse,
    MarketDemandListing,
    ProductListing,
)
from apps.smehub.onboarding.models import Business, EntrepreneurProfile

logger = logging.getLogger(__name__)
User = get_user_model()

DEMO_PASSWORD = "smehub-demo-2026"  # noqa: S105 - demo only


_BUYERS = [
    ("Nairobi Wholesale Co.", "wholesale", ["Agribusiness", "Trade"], ["KE"]),
    ("Mombasa Export Group", "exporter", ["Agribusiness"], ["KE"]),
    ("Kampala Retail Holdings", "retail", ["Trade"], ["UG"]),
    ("Cape Town Processing Co.", "processor", ["Agribusiness"], ["ZA"]),
    ("West Africa Foods Inc.", "wholesale", ["Agribusiness"], ["GH", "NG"]),
    ("Kigali Fresh Markets", "retail", ["Agribusiness"], ["RW"]),
    ("EthioCoffee Exporters", "exporter", ["Agriculture"], ["ET"]),
    ("Lagos Institutional Buyers", "institutional", ["Health", "Education"], ["NG"]),
    ("Tanzania Cooperative Stores", "wholesale", ["Agribusiness"], ["TZ"]),
    ("Sahel Procurement Authority", "government", ["Agriculture"], ["NE", "ML"]),
    ("Pan-African Restaurants", "retail", ["Tourism"], ["KE", "UG", "ZA"]),
    ("Sudan Grain Traders", "wholesale", ["Agriculture"], ["SD"]),
    ("Botswana Healthcare Buyers", "institutional", ["Health"], ["BW"]),
    ("Zimbabwe Manufacturing Hub", "processor", ["Manufacturing"], ["ZW"]),
    ("Mozambique Aquatic Products", "exporter", ["Aquaculture"], ["MZ"]),
]

_PRODUCT_TEMPLATES = [
    ("Organic Maize 50kg", "Agriculture", "USD 32 / 50kg", "in_stock"),
    ("Premium Arabica Coffee Beans", "Agriculture", "USD 7.50 / kg", "seasonal"),
    ("Solar Irrigation Pump Kits", "Energy", "USD 1,200 / unit", "to_order"),
    ("Cold-Chain Yogurt 500ml", "Agribusiness", "USD 1.20 / unit", "in_stock"),
    ("Beekeeping Starter Kit", "Agriculture", "USD 450 / kit", "in_stock"),
    ("Mobile Soil Sensors", "Tech", "USD 220 / set", "to_order"),
    ("Cassava Flour 25kg", "Agribusiness", "USD 18 / 25kg", "in_stock"),
    ("AgriPay Wallet App", "FinTech", "POA", "in_stock"),
    ("Biogas Digester (Family)", "Energy", "USD 800 / unit", "to_order"),
    ("Tilapia Fingerlings", "Aquaculture", "USD 0.30 / fingerling", "seasonal"),
    ("Drought-Tolerant Sorghum Seed", "Agriculture", "USD 45 / 25kg", "seasonal"),
    ("Mobile Cassava Processor", "Manufacturing", "USD 5,500 / unit", "to_order"),
    ("Halal-Certified Poultry", "Livestock", "USD 4.20 / kg", "in_stock"),
    ("Solar Maize Dryer", "Energy", "USD 2,800 / unit", "to_order"),
    ("Eco-Tourism Day Pack", "Tourism", "USD 80 / package", "in_stock"),
    ("Beekeeping Veil & Suit", "Agriculture", "USD 65 / set", "in_stock"),
    ("AquaPure Water Filter", "Water", "USD 110 / unit", "in_stock"),
    ("Smart Livestock Tag", "Livestock", "USD 12 / tag", "to_order"),
    ("Solar Cold Storage Unit", "Energy", "USD 4,200 / unit", "to_order"),
    ("Pasteurised Milk 1L", "Agribusiness", "USD 1.10 / unit", "in_stock"),
    ("Mango Pulp Concentrate", "Agribusiness", "USD 5 / kg", "seasonal"),
    ("EduTech Tablet Bundle", "Education", "USD 320 / unit", "in_stock"),
    ("HerbalRemedy Wellness Pack", "Health", "USD 28 / pack", "in_stock"),
    ("Smart Cotton Picker (Manual)", "Agriculture", "USD 95 / unit", "in_stock"),
    ("RUFORUM Branded Sorghum Mix", "Agribusiness", "USD 40 / 25kg", "in_stock"),
]

_DEMAND_TEMPLATES = [
    ("Seeking 200t organic maize for Q3", "Long-term off-take agreement.", "procurement", ["Agriculture"], ["KE"], "200 tonnes"),
    ("Bulk Arabica coffee buyer", "USD-priced quarterly contracts.", "offtake", ["Agriculture"], ["ET", "RW"], "5,000 kg"),
    ("Cold-chain logistics partners wanted", "Routes Nairobi → Kampala weekly.", "tender", ["Transport"], ["KE", "UG"], "2 trucks/week"),
    ("Solar irrigation pumps for Sahel", "Looking for 500 units across 3 sites.", "tender", ["Energy"], ["NE", "ML"], "500 units"),
    ("Smallholder yogurt aggregation", "Need 4,000 units / week, food-grade.", "procurement", ["Agribusiness"], ["UG"], "4,000 units / week"),
    ("Aquaculture fingerlings — 1M units", "Bulk request for restocking project.", "procurement", ["Aquaculture"], ["MZ", "TZ"], "1,000,000 units"),
    ("EdTech tablets for rural schools", "USD 200K education ministry tender.", "tender", ["Education"], ["KE"], "1,000 tablets"),
    ("Halal-certified poultry suppliers", "Need monthly supply for institutional buyer.", "procurement", ["Livestock"], ["NG"], "10 tonnes / month"),
]


def _ensure_user(email: str, *, first: str, last: str, role: str) -> User:
    user, created = User.objects.get_or_create(
        email=email,
        defaults={
            "first_name": first,
            "last_name": last,
            "is_active": True,
            "email_verified": True,
            "role": role,
        },
    )
    if created:
        user.password = make_password(DEMO_PASSWORD)
        user.save(update_fields=["password"])
    return user


def _ensure_admin() -> User:
    return _ensure_user(
        "smehub-admin@ruforum.org",
        first="Sara",
        last="Admin",
        role=UserRole.SME_ADMIN,
    )


def _seed_buyers(admin: User) -> int:
    created = 0
    for idx, (name, org_type, sectors, geo) in enumerate(_BUYERS):
        user = _ensure_user(
            f"buyer{idx + 1}@ruforum.org",
            first=name.split(" ")[0],
            last="Buyer",
            role=UserRole.BUYER,
        )
        entry, was_created = BuyerRegistryEntry.objects.get_or_create(
            user=user,
            defaults={
                "organisation_name": name,
                "org_type": org_type,
                "sectors_sourced": sectors,
                "geographic_coverage": [to_country_name(c) for c in geo],
                "contact_email": user.email,
                "description": f"{name} sources at scale across {', '.join(sectors)}.",
                "typical_volume": "Bulk monthly contracts.",
            },
        )
        if was_created:
            created += 1
        if entry.verification_status == BuyerRegistryEntry.Status.PENDING:
            entry.verify(by_user=admin)
            entry.save()
    return created


def _seed_product_listings() -> int:
    profile_with_business = list(
        Business.objects.filter(
            verification_status=Business.Status.VERIFIED,
        ).select_related("entrepreneur__user")[:8]
    )
    if not profile_with_business:
        return 0
    created = 0
    rng = random.Random(7)
    for idx, (name, sector, pricing, availability) in enumerate(_PRODUCT_TEMPLATES):
        business = profile_with_business[idx % len(profile_with_business)]
        listing, was_created = ProductListing.objects.get_or_create(
            entrepreneur=business.entrepreneur,
            business=business,
            name=name,
            defaults={
                "description": f"{name} — produced by {business.name}. Quality assured.",
                "sector": sector,
                "pricing": pricing,
                "availability": availability,
                "geographic_reach": [to_country_name(c) for c in rng.sample(["KE", "UG", "TZ", "RW", "ZA", "NG", "ET"], k=3)],
            },
        )
        if was_created:
            created += 1
        # Publish ~80%
        if idx % 5 != 0 and listing.status == ProductListing.Status.DRAFT:
            listing.status = ProductListing.Status.PUBLISHED
            listing.published_at = timezone.now()
            listing.save(update_fields=["status", "published_at"])
    return created


def _seed_demand_listings() -> int:
    buyers = list(BuyerRegistryEntry.objects.filter(verification_status=BuyerRegistryEntry.Status.VERIFIED))
    if not buyers:
        return 0
    created = 0
    now = timezone.now()
    for idx, (title, description, kind, sectors, geo, qty) in enumerate(_DEMAND_TEMPLATES):
        buyer = buyers[idx % len(buyers)]
        listing, was_created = MarketDemandListing.objects.get_or_create(
            buyer=buyer,
            title=title,
            defaults={
                "description": description,
                "kind": kind,
                "sector_targeting": sectors,
                "geographic_targeting": [to_country_name(c) for c in geo],
                "quantity": qty,
                "deadline": now + timedelta(days=14 + idx * 3),
            },
        )
        if was_created:
            created += 1
    return created


def _seed_demand_responses() -> int:
    open_listings = list(
        MarketDemandListing.objects.filter(status=MarketDemandListing.Status.OPEN)[:6]
    )
    businesses = list(
        Business.objects.filter(verification_status=Business.Status.VERIFIED).select_related("entrepreneur")[:6]
    )
    if not open_listings or not businesses:
        return 0
    created = 0
    outcome_cycle = [
        DemandResponse.Status.SUBMITTED,
        DemandResponse.Status.SHORTLISTED,
        DemandResponse.Status.AWARDED,
        DemandResponse.Status.DECLINED,
    ]
    counter = 0
    for listing in open_listings:
        for business in businesses[:3]:
            response, was_created = DemandResponse.objects.get_or_create(
                demand_listing=listing,
                business=business,
                defaults={
                    "entrepreneur": business.entrepreneur,
                    "message": f"{business.name} can supply {listing.title.lower()} at scale.",
                    "pricing_offer": "Open to negotiation pending volume.",
                },
            )
            if was_created:
                created += 1
            outcome = outcome_cycle[counter % len(outcome_cycle)]
            if outcome != DemandResponse.Status.SUBMITTED and response.status == DemandResponse.Status.SUBMITTED:
                response.status = outcome
                response.decided_at = timezone.now()
                response.decision_note = "Seeder-generated decision."
                response.save(update_fields=["status", "decided_at", "decision_note"])
            counter += 1
    return created


@transaction.atomic
def seed() -> dict:
    admin = _ensure_admin()
    buyers = _seed_buyers(admin)
    products = _seed_product_listings()
    demand = _seed_demand_listings()
    responses = _seed_demand_responses()
    return {
        "buyers": buyers,
        "products": products,
        "demand_listings": demand,
        "demand_responses": responses,
    }
