"""End-to-end tests for the reconcile() function."""
import json
import tempfile
from pathlib import Path

import pytest

from kanoniv.source import Source
from kanoniv.spec import Spec

# These tests require the native extension (maturin develop) to be installed.
# They will be skipped if the native module is not available.
try:
    from kanoniv._native import reconcile_local

    HAS_NATIVE = True
except ImportError:
    HAS_NATIVE = False

pytestmark = pytest.mark.skipif(not HAS_NATIVE, reason="Native extension not built")

SPEC_YAML = """\
api_version: kanoniv/v2
identity_version: test_v1.0
entity:
  name: customer
sources:
  - name: crm
    system: csv
    table: crm_export
    id: id
    attributes:
      email: email
      name: name
  - name: orders
    system: csv
    table: order_export
    id: id
    attributes:
      email: email
      name: name
blocking:
  strategy: composite
  keys:
    - [email]
rules:
  - name: email_exact
    type: exact
    field: email
    weight: 1.0
decision:
  thresholds:
    match: 0.8
    review: 0.5
  conflict_strategy: prefer_high_confidence
"""


@pytest.fixture
def crm_csv(tmp_path):
    p = tmp_path / "crm.csv"
    p.write_text(
        "id,email,name\n"
        "c1,alice@example.com,Alice Smith\n"
        "c2,bob@example.com,Bob Jones\n"
        "c3,carol@example.com,Carol White\n"
    )
    return str(p)


@pytest.fixture
def orders_csv(tmp_path):
    p = tmp_path / "orders.csv"
    p.write_text(
        "id,email,name\n"
        "o1,alice@example.com,Alice S.\n"
        "o2,dave@example.com,Dave Brown\n"
    )
    return str(p)


class TestReconcileEndToEnd:
    def test_overlapping_emails_merge(self, crm_csv, orders_csv):
        from kanoniv.reconcile import reconcile

        crm = Source.from_csv("crm", crm_csv, primary_key="id")
        orders = Source.from_csv("orders", orders_csv, primary_key="id")
        spec = Spec.from_string(SPEC_YAML)

        result = reconcile(sources=[crm, orders], spec=spec)

        # Alice appears in both sources — should be merged into one cluster
        # Total entities: 5 (c1, c2, c3, o1, o2)
        # Expected clusters: 4 (alice merged, bob, carol, dave as singletons)
        assert result.cluster_count == 4

    def test_golden_records_count_matches_clusters(self, crm_csv, orders_csv):
        from kanoniv.reconcile import reconcile

        crm = Source.from_csv("crm", crm_csv, primary_key="id")
        orders = Source.from_csv("orders", orders_csv, primary_key="id")
        spec = Spec.from_string(SPEC_YAML)

        result = reconcile(sources=[crm, orders], spec=spec)
        assert len(result.golden_records) == result.cluster_count

    def test_decisions_populated(self, crm_csv, orders_csv):
        from kanoniv.reconcile import reconcile

        crm = Source.from_csv("crm", crm_csv, primary_key="id")
        orders = Source.from_csv("orders", orders_csv, primary_key="id")
        spec = Spec.from_string(SPEC_YAML)

        result = reconcile(sources=[crm, orders], spec=spec)
        # At least one merge decision (alice)
        assert len(result.decisions) >= 1

    def test_telemetry_populated(self, crm_csv, orders_csv):
        from kanoniv.reconcile import reconcile

        crm = Source.from_csv("crm", crm_csv, primary_key="id")
        orders = Source.from_csv("orders", orders_csv, primary_key="id")
        spec = Spec.from_string(SPEC_YAML)

        result = reconcile(sources=[crm, orders], spec=spec)
        assert "rule_telemetry" in result.telemetry
        assert "pairs_evaluated" in result.telemetry

    def test_merge_rate(self, crm_csv, orders_csv):
        from kanoniv.reconcile import reconcile

        crm = Source.from_csv("crm", crm_csv, primary_key="id")
        orders = Source.from_csv("orders", orders_csv, primary_key="id")
        spec = Spec.from_string(SPEC_YAML)

        result = reconcile(sources=[crm, orders], spec=spec)
        # 5 entities, 4 clusters → merge_rate = 1 - 4/5 = 0.2
        assert result.merge_rate == pytest.approx(0.2)

    def test_no_overlap_no_merges(self, tmp_path):
        from kanoniv.reconcile import reconcile

        csv_a = tmp_path / "a.csv"
        csv_a.write_text("id,email,name\na1,x@x.com,X\n")
        csv_b = tmp_path / "b.csv"
        csv_b.write_text("id,email,name\nb1,y@y.com,Y\n")

        src_a = Source.from_csv("a", str(csv_a), primary_key="id")
        src_b = Source.from_csv("b", str(csv_b), primary_key="id")
        spec = Spec.from_string(SPEC_YAML)

        result = reconcile(sources=[src_a, src_b], spec=spec)
        assert result.cluster_count == 2
        assert result.merge_rate == 0.0
