import pytest
from app.services.valuation import (
    _parse_valuation_band, _domain_intrinsic_score,
    _classify_monetization, _estimate_monthly_traffic,
    valuate_domain,
)


class TestParseValuationBand:
    def test_standard_range(self):
        low, high = _parse_valuation_band("5000-20000")
        assert low == 5000
        assert high == 20000

    def test_with_dollar_signs(self):
        low, high = _parse_valuation_band("$5,000-$20,000")
        assert low == 5000
        assert high == 20000

    def test_single_value(self):
        low, high = _parse_valuation_band("10000")
        assert low == 10000
        assert high == 30000

    def test_empty_returns_default(self):
        low, high = _parse_valuation_band("")
        assert low == 5000
        assert high == 20000

    def test_none_returns_default(self):
        low, high = _parse_valuation_band(None)
        assert low == 5000
        assert high == 20000

    def test_garbage_input_returns_default(self):
        low, high = _parse_valuation_band("not a number")
        assert low == 5000
        assert high == 20000


class TestDomainIntrinsicScore:
    def test_short_com_domain(self):
        score = _domain_intrinsic_score("abc.com")
        assert score["length"] == 3
        assert score["length_score"] == 1.0
        assert score["has_hyphens"] is False
        assert score["has_numbers"] is False
        assert score["domain_only_value"] > 0

    def test_long_domain_scores_lower(self):
        short = _domain_intrinsic_score("abc.com")
        long = _domain_intrinsic_score("verylongdomainnamehere.com")
        assert short["raw_score"] > long["raw_score"]

    def test_hyphenated_domain_penalized(self):
        clean = _domain_intrinsic_score("testdomain.com")
        hyphen = _domain_intrinsic_score("test-domain.com")
        assert clean["raw_score"] > hyphen["raw_score"]
        assert hyphen["has_hyphens"] is True

    def test_numeric_domain_penalized(self):
        clean = _domain_intrinsic_score("testdomain.com")
        numeric = _domain_intrinsic_score("test123.com")
        assert clean["raw_score"] > numeric["raw_score"]
        assert numeric["has_numbers"] is True

    def test_com_tld_scores_higher_than_xyz(self):
        com = _domain_intrinsic_score("test.com")
        xyz = _domain_intrinsic_score("test.xyz")
        assert com["tld_multiplier"] > xyz["tld_multiplier"]

    def test_result_fields(self):
        score = _domain_intrinsic_score("test.com")
        required = {"domain_name", "name_part", "tld", "length", "tld_multiplier",
                     "length_score", "has_hyphens", "has_numbers", "raw_score", "domain_only_value"}
        assert required.issubset(set(score.keys()))

    def test_raw_score_capped_at_1(self):
        score = _domain_intrinsic_score("ai.com")
        assert score["raw_score"] <= 1.0


class TestClassifyMonetization:
    def test_affiliate(self):
        assert _classify_monetization("affiliate marketing") == "affiliate"

    def test_saas(self):
        assert _classify_monetization("SaaS subscription") == "saas"

    def test_digital(self):
        assert _classify_monetization("digital products") == "digital"

    def test_ecommerce(self):
        assert _classify_monetization("e-commerce store") == "ecommerce_dropship"

    def test_services(self):
        assert _classify_monetization("consulting agency") == "services"

    def test_empty_defaults_to_affiliate(self):
        assert _classify_monetization("") == "affiliate"

    def test_none_defaults_to_affiliate(self):
        assert _classify_monetization(None) == "affiliate"

    def test_unknown_defaults_to_affiliate(self):
        assert _classify_monetization("something random") == "affiliate"


class TestEstimateMonthlyTraffic:
    def test_returns_required_fields(self, sample_niche):
        domain_score = _domain_intrinsic_score("test.com")
        traffic = _estimate_monthly_traffic(sample_niche, domain_score)
        assert "monthly_visitors_low" in traffic
        assert "monthly_visitors_mid" in traffic
        assert "monthly_visitors_high" in traffic
        assert traffic["monthly_visitors_low"] <= traffic["monthly_visitors_mid"] <= traffic["monthly_visitors_high"]

    def test_traffic_is_positive(self, sample_niche):
        domain_score = _domain_intrinsic_score("test.com")
        traffic = _estimate_monthly_traffic(sample_niche, domain_score)
        assert traffic["monthly_visitors_low"] > 0


class TestValuateDomain:
    def test_full_valuation(self, sample_analysis):
        result = valuate_domain("test.com", sample_analysis)
        assert "domain_intrinsic" in result
        assert "niche_valuations" in result
        assert len(result["niche_valuations"]) > 0

    def test_niche_valuation_has_model_data(self, sample_analysis):
        result = valuate_domain("test.com", sample_analysis)
        niche = result["niche_valuations"][0]
        assert "revenue_models" in niche or "best_model" in niche
        if "revenue_models" in niche:
            assert len(niche["revenue_models"]) > 0
        if "best_model" in niche:
            assert isinstance(niche["best_model"], dict)

    def test_empty_analysis_handles_gracefully(self):
        result = valuate_domain("test.com", {"niches": []})
        assert "domain_intrinsic" in result
        assert len(result["niche_valuations"]) == 0
