"""Tests for SME-Hub MarketValidation (Phase 6.3).

Coverage:
* validate_market_fit creates a row, computes average_score, and signals MEL
* WTP currency validation
* Strong-signal heuristic (LOI / PILOT or all-scores>=4)
* Owner gating (entrepreneur or admin only)
"""
from __future__ import annotations

from decimal import Decimal

import pytest
from django.contrib.auth import get_user_model

from apps.core.permissions.roles import UserRole
from apps.smehub.marketplace import services
from apps.smehub.marketplace.models import (
    BuyerRegistryEntry,
    MarketValidation,
    ProductListing,
)
from apps.smehub.onboarding.models import (
    Business,
    BusinessStage,
    EntrepreneurProfile,
)

User = get_user_model()
pytestmark = pytest.mark.django_db


@pytest.fixture
def admin():
    return User.objects.create_user(
        email="admin@example.com", password="x", is_superuser=True, is_staff=True,
        role=UserRole.SYSTEM_ADMIN,
    )


@pytest.fixture
def entrepreneur(admin):
    user = User.objects.create_user(
        email="ent@example.com", password="x", role=UserRole.ENTREPRENEUR,
    )
    profile = EntrepreneurProfile.objects.create(user=user, country="UG", organisation="Test Co")
    profile.verify(by_user=admin)
    profile.save()
    return profile


@pytest.fixture
def verified_business(entrepreneur, admin):
    biz = Business.objects.create(
        entrepreneur=entrepreneur,
        name="GrainCo",
        sector="Agriculture",
        business_stage=BusinessStage.MVP,
        country="UG",
    )
    biz.verify(by_user=admin)
    biz.save()
    return biz


@pytest.fixture
def listing(entrepreneur, verified_business):
    return services.create_product_listing(
        entrepreneur=entrepreneur,
        business=verified_business,
        name="Solar maize dryer",
        sector="Agriculture",
        description="60kg/day solar dryer.",
    )


# ---------------------------------------------------------------------------
# Happy path
# ---------------------------------------------------------------------------

def test_validate_market_fit_creates_record_and_audits(entrepreneur, listing):
    validation = services.validate_market_fit(
        product_listing=listing,
        recorded_by=entrepreneur.user,
        method=MarketValidation.Method.INTERVIEW,
        problem_fit_score=4,
        solution_fit_score=5,
        willingness_to_pay_score=3,
        validator_name="Buyer #1",
        notes="Interested in pilot.",
    )
    assert validation.pk is not None
    assert validation.business_id == listing.business_id
    assert validation.average_score == Decimal("4.00")


def test_validate_market_fit_requires_currency_when_wtp_amount_set(entrepreneur, listing):
    with pytest.raises(services.MarketplaceStateError):
        services.validate_market_fit(
            product_listing=listing,
            recorded_by=entrepreneur.user,
            method=MarketValidation.Method.SURVEY,
            problem_fit_score=3,
            solution_fit_score=3,
            willingness_to_pay_score=3,
            willingness_to_pay_amount=Decimal("100.00"),
            currency="",
        )


def test_validate_market_fit_strong_signal_when_all_scores_4_plus(entrepreneur, listing):
    validation = services.validate_market_fit(
        product_listing=listing,
        recorded_by=entrepreneur.user,
        method=MarketValidation.Method.SURVEY,
        problem_fit_score=4,
        solution_fit_score=5,
        willingness_to_pay_score=4,
    )
    assert validation.has_strong_signal is True


def test_validate_market_fit_strong_signal_when_loi_or_pilot(entrepreneur, listing):
    validation = services.validate_market_fit(
        product_listing=listing,
        recorded_by=entrepreneur.user,
        method=MarketValidation.Method.LOI,
        problem_fit_score=2,
        solution_fit_score=2,
        willingness_to_pay_score=2,
    )
    assert validation.has_strong_signal is True


def test_validate_market_fit_weak_signal_for_low_scores(entrepreneur, listing):
    validation = services.validate_market_fit(
        product_listing=listing,
        recorded_by=entrepreneur.user,
        method=MarketValidation.Method.INTERVIEW,
        problem_fit_score=2,
        solution_fit_score=3,
        willingness_to_pay_score=2,
    )
    assert validation.has_strong_signal is False


def test_validate_market_fit_blocked_for_unrelated_user(listing):
    """Random users (not the owning entrepreneur or an admin) are rejected."""
    other = User.objects.create_user(email="other@example.com", password="x", role=UserRole.LEARNER)
    with pytest.raises(services.MarketplaceStateError):
        services.validate_market_fit(
            product_listing=listing,
            recorded_by=other,
            method=MarketValidation.Method.INTERVIEW,
            problem_fit_score=3,
            solution_fit_score=3,
            willingness_to_pay_score=3,
        )


def test_validate_market_fit_emits_mel_event(entrepreneur, listing):
    from apps.mel.tracking.models import TrackingMilestone

    validation = services.validate_market_fit(
        product_listing=listing,
        recorded_by=entrepreneur.user,
        method=MarketValidation.Method.PILOT,
        problem_fit_score=4,
        solution_fit_score=4,
        willingness_to_pay_score=4,
    )
    assert TrackingMilestone.objects.filter(
        event_type="smehub_market_validation_recorded",
        source_id=str(validation.pk),
    ).exists()
