# Generated by Django 4.2.24 on 2025-11-14 09:53

import uuid
from django.db import migrations, models


def initialize_dual_tree_versioning(apps, schema_editor):
    """
    Initialize dual-tree structure for existing documents.

    According to the architecture:
    - Step 1: Initialize Document trees (version_tree_id, is_current, parent=None)
    - Step 2: Create DocumentPath records from corpus.documents relationships

    Note: CorpusDocumentFolder was never deployed to production, so we create
    DocumentPath records from the corpus.documents many-to-many relationship.

    IMPORTANT: This migration MUST run before the UniqueConstraint is added.
    Migration 0023 adds version_tree_id as nullable without a default to avoid
    all existing rows getting the same UUID (which would violate the constraint).
    This function assigns unique UUIDs to each document, making it safe to add
    the constraint afterward.
    """
    Document = apps.get_model('documents', 'Document')
    DocumentPath = apps.get_model('documents', 'DocumentPath')
    Corpus = apps.get_model('corpuses', 'Corpus')

    # Step 1: Initialize Document trees
    # Note: TreeNode fields (parent) are already present from the model
    doc_count = 0
    for doc in Document.objects.all():
        # Only initialize if version_tree_id is None (safeguard for re-running migration)
        if not doc.version_tree_id:
            doc.version_tree_id = uuid.uuid4()
            doc.is_current = True
            # parent is already None by default (no version history for existing docs)
            doc.save(update_fields=['version_tree_id', 'is_current'])
            doc_count += 1

    print(f"Initialized version trees for {doc_count} documents")

    # Step 2: Create DocumentPath records from existing relationships
    path_count = 0
    for corpus in Corpus.objects.prefetch_related('documents').all():
        for doc in corpus.documents.all():
            # Check if DocumentPath already exists (safeguard for re-running migration)
            existing = DocumentPath.objects.filter(
                document=doc,
                corpus=corpus,
                is_current=True,
                is_deleted=False
            ).exists()

            if not existing:
                # Generate path from document title (fallback to id if no title)
                path = f"/{doc.title or f'document-{doc.id}'}"

                # Create initial DocumentPath
                DocumentPath.objects.create(
                    document=doc,
                    corpus=corpus,
                    folder=None,  # Root level by default
                    path=path,
                    version_number=1,  # All existing docs are v1
                    parent=None,  # All are roots initially
                    is_current=True,
                    is_deleted=False,
                    creator=doc.creator,
                    # BaseOCModel fields inherited
                    backend_lock=False,
                    is_public=doc.is_public if hasattr(doc, 'is_public') else False,
                )
                path_count += 1

    print(f"Created {path_count} DocumentPath records")
    print(f"Migration complete: {doc_count} documents initialized, {path_count} paths created")


class Migration(migrations.Migration):

    dependencies = [
        ("documents", "0023_documentpath_documentpathgroupobjectpermission_and_more"),
        ("corpuses", "0025_corpusfolder_is_public"),  # Need Corpus model
    ]

    operations = [
        # Step 1: Populate unique UUIDs for all existing documents
        migrations.RunPython(
            initialize_dual_tree_versioning,
            reverse_code=migrations.RunPython.noop,
        ),
        # Step 2: Make version_tree_id non-nullable with a default for new documents
        # This is safe now because all existing rows have unique UUIDs from Step 1
        migrations.AlterField(
            model_name="document",
            name="version_tree_id",
            field=models.UUIDField(
                db_index=True,
                default=uuid.uuid4,
                help_text="Groups all content versions of same logical document. Implements Rule C1.",
            ),
        ),
        # Step 3: Add the unique constraint
        # This is safe now because each document has a unique version_tree_id
        migrations.AddConstraint(
            model_name="document",
            constraint=models.UniqueConstraint(
                condition=models.Q(("is_current", True)),
                fields=("version_tree_id",),
                name="one_current_per_version_tree",
            ),
        ),
    ]
