from __future__ import annotations

from datetime import timedelta
from io import StringIO

from django.core.management import call_command
from django.test import TestCase
from django.utils import timezone

from core.models import (
    MemoryChangeRequest,
    MemoryItem,
    MessageEvent,
    User,
    WorkspaceConversation,
)


class MemoryPipelineCommandTests(TestCase):
    def setUp(self):
        self.user = User.objects.create_user(
            username="memory-pipeline-user",
            email="memory-pipeline@example.com",
            password="pw",
        )
        self.conversation = WorkspaceConversation.objects.create(
            user=self.user,
            platform_type="signal",
            title="Pipeline Scope",
            platform_thread_id="pipeline-thread-1",
        )

    def test_memory_suggest_from_messages_creates_pending_request(self):
        MessageEvent.objects.create(
            user=self.user,
            conversation=self.conversation,
            ts=1700000000000,
            direction="in",
            text="I prefer short status updates and bullet points.",
            source_system="signal",
        )

        out = StringIO()
        call_command(
            "memory_suggest_from_messages",
            user_id=str(self.user.id),
            limit_messages=50,
            max_items=10,
            stdout=out,
        )
        rendered = out.getvalue()
        self.assertIn("memory-suggest-from-messages", rendered)
        self.assertGreaterEqual(MemoryItem.objects.filter(user=self.user).count(), 1)
        self.assertGreaterEqual(
            MemoryChangeRequest.objects.filter(
                user=self.user, status="pending"
            ).count(),
            1,
        )

    def test_memory_hygiene_expires_and_detects_contradictions(self):
        expired = MemoryItem.objects.create(
            user=self.user,
            conversation=self.conversation,
            memory_kind="fact",
            status="active",
            content={"field": "likes", "text": "calls in the evening"},
            confidence_score=0.6,
            expires_at=timezone.now() - timedelta(days=1),
        )
        MemoryItem.objects.create(
            user=self.user,
            conversation=self.conversation,
            memory_kind="fact",
            status="active",
            content={"field": "timezone", "text": "UTC+1"},
            confidence_score=0.7,
        )
        MemoryItem.objects.create(
            user=self.user,
            conversation=self.conversation,
            memory_kind="fact",
            status="active",
            content={"field": "timezone", "text": "UTC-5"},
            confidence_score=0.7,
        )

        out = StringIO()
        call_command(
            "memory_hygiene",
            user_id=str(self.user.id),
            stdout=out,
        )
        rendered = out.getvalue()
        self.assertIn("memory-hygiene", rendered)

        expired.refresh_from_db()
        self.assertEqual("deprecated", expired.status)
        contradiction_requests = MemoryChangeRequest.objects.filter(
            user=self.user,
            status="pending",
            action="update",
            reason__icontains="Contradiction",
        ).count()
        self.assertGreaterEqual(contradiction_requests, 1)
