from __future__ import annotations

from django.test import TestCase

from core.models import User, WorkspaceConversation, WorkspaceMetricSnapshot
from core.views.workspace import _history_points
from core.workspace import DENSITY_POINT_CAPS, compact_snapshot_rows, downsample_points


class WorkspaceGraphSamplingTests(TestCase):
    def test_downsample_points_respects_density_caps(self):
        base_ts = 1_700_000_000_000
        points = []
        for idx in range(1_000):
            points.append(
                {
                    "x": "",
                    "y": float(idx % 100),
                    "ts_ms": base_ts + (idx * 60_000),
                }
            )
        low = downsample_points(points, density="low")
        high = downsample_points(points, density="high")
        self.assertLessEqual(len(low), DENSITY_POINT_CAPS["low"])
        self.assertLessEqual(len(high), DENSITY_POINT_CAPS["high"])
        self.assertGreaterEqual(len(high), len(low))

    def test_history_points_uses_source_event_ts_for_graph_x(self):
        user = User.objects.create_user("graph-user", "graph@example.com", "x")
        conversation = WorkspaceConversation.objects.create(
            user=user,
            title="Graph",
            platform_type="whatsapp",
        )
        base_ts = 1_700_000_000_000
        for idx in range(300):
            WorkspaceMetricSnapshot.objects.create(
                conversation=conversation,
                source_event_ts=base_ts + (idx * 60_000),
                stability_state=WorkspaceConversation.StabilityState.CALIBRATING,
                stability_score=None,
                stability_confidence=0.0,
                stability_sample_messages=idx + 1,
                stability_sample_days=1,
                commitment_inbound_score=None,
                commitment_outbound_score=None,
                commitment_confidence=0.0,
                inbound_messages=0,
                outbound_messages=idx + 1,
                reciprocity_score=None,
                continuity_score=None,
                response_score=None,
                volatility_score=None,
                inbound_response_score=None,
                outbound_response_score=None,
                balance_inbound_score=None,
                balance_outbound_score=None,
            )
        points = _history_points(
            conversation, "stability_sample_messages", density="low"
        )
        self.assertTrue(points)
        self.assertLessEqual(len(points), DENSITY_POINT_CAPS["low"])
        first_x = str(points[0].get("x") or "")
        self.assertIn("2023", first_x)

    def test_compact_snapshot_rows_drops_outside_cutoff_and_buckets(self):
        rows = []
        now_ts = 1_900_000_000_000
        old_ts = now_ts - (400 * 24 * 60 * 60 * 1000)
        for idx in range(30):
            rows.append(
                {
                    "id": idx + 1,
                    "source_event_ts": old_ts + (idx * 60_000),
                    "computed_at": None,
                }
            )
        keep = compact_snapshot_rows(
            snapshot_rows=rows,
            now_ts_ms=now_ts,
            cutoff_ts_ms=now_ts - (365 * 24 * 60 * 60 * 1000),
        )
        self.assertEqual(set(), keep)
