#!/usr/bin/env python3
"""
Test script for v2.0 to v3.0 migration

This script creates a v2.0 project, saves it, then loads it back
to verify that the migration to v3.0 works correctly.
"""

import os
import sys
import tempfile
import json
import zipfile
from datetime import datetime

# Add pyPhotoAlbum to path
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))

from pyPhotoAlbum.project import Project, Page
from pyPhotoAlbum.models import ImageData, TextBoxData
from pyPhotoAlbum.project_serializer import save_to_zip, load_from_zip
from pyPhotoAlbum.version_manager import CURRENT_DATA_VERSION


def create_v2_project_json():
    """Create a v2.0 project JSON (without UUIDs, timestamps, project_id)"""
    return {
        "name": "Test Project v2.0",
        "folder_path": "./test_project",
        "page_size_mm": [140, 140],
        "working_dpi": 300,
        "export_dpi": 300,
        "has_cover": False,
        "data_version": "2.0",
        "pages": [
            {
                "page_number": 1,
                "is_cover": False,
                "is_double_spread": False,
                "manually_sized": False,
                "layout": {
                    "size": [140, 140],
                    "background_color": [1.0, 1.0, 1.0],
                    "elements": [
                        {
                            "type": "textbox",
                            "position": [10, 10],
                            "size": [100, 50],
                            "rotation": 0,
                            "z_index": 0,
                            "text_content": "Hello v2.0",
                            "font_settings": {"family": "Arial", "size": 12, "color": [0, 0, 0]},
                            "alignment": "left",
                        }
                    ],
                    "snapping_system": {"snap_threshold_mm": 5.0, "grid_size_mm": 10.0},
                },
            }
        ],
        "history": {"undo_stack": [], "redo_stack": [], "max_history": 100},
        "asset_manager": {"reference_counts": {}},
    }


def test_migration():
    """Test v2.0 to v3.0 migration"""
    print("=" * 60)
    print("Testing v2.0 to v3.0 Migration")
    print("=" * 60)

    with tempfile.TemporaryDirectory() as temp_dir:
        # Create a fake v2.0 .ppz file
        v2_file = os.path.join(temp_dir, "test_v2.ppz")

        print(f"\n1. Creating v2.0 project file: {v2_file}")
        v2_data = create_v2_project_json()

        with zipfile.ZipFile(v2_file, "w", zipfile.ZIP_DEFLATED) as zipf:
            project_json = json.dumps(v2_data, indent=2)
            zipf.writestr("project.json", project_json)

        print(f"   ✓ Created v2.0 project with {len(v2_data['pages'])} page(s)")
        print(f"   ✓ Version: {v2_data['data_version']}")

        # Load the v2.0 file (should trigger migration)
        print(f"\n2. Loading v2.0 project (migration should occur)...")

        try:
            project = load_from_zip(v2_file)
            print(f"   ✓ Project loaded successfully")
            print(f"   ✓ Project name: {project.name}")

            # Verify migration
            print(f"\n3. Verifying migration to v3.0...")

            # Check project-level fields
            assert hasattr(project, "project_id"), "Missing project_id"
            assert hasattr(project, "created"), "Missing created timestamp"
            assert hasattr(project, "last_modified"), "Missing last_modified timestamp"
            print(f"   ✓ Project has project_id: {project.project_id}")
            print(f"   ✓ Project has created: {project.created}")
            print(f"   ✓ Project has last_modified: {project.last_modified}")

            # Check page-level fields
            assert len(project.pages) > 0, "No pages in project"
            page = project.pages[0]
            assert hasattr(page, "uuid"), "Page missing uuid"
            assert hasattr(page, "created"), "Page missing created"
            assert hasattr(page, "last_modified"), "Page missing last_modified"
            assert hasattr(page, "deleted"), "Page missing deleted flag"
            print(f"   ✓ Page 1 has uuid: {page.uuid}")
            print(f"   ✓ Page 1 has timestamps and deletion tracking")

            # Check element-level fields
            assert len(page.layout.elements) > 0, "No elements in page"
            element = page.layout.elements[0]
            assert hasattr(element, "uuid"), "Element missing uuid"
            assert hasattr(element, "created"), "Element missing created"
            assert hasattr(element, "last_modified"), "Element missing last_modified"
            assert hasattr(element, "deleted"), "Element missing deleted flag"
            print(f"   ✓ Element has uuid: {element.uuid}")
            print(f"   ✓ Element has timestamps and deletion tracking")

            # Save as v3.0 and verify
            print(f"\n4. Saving migrated project as v3.0...")
            v3_file = os.path.join(temp_dir, "test_v3.ppz")
            success, error = save_to_zip(project, v3_file)
            assert success, f"Save failed: {error}"
            print(f"   ✓ Saved to: {v3_file}")

            # Verify v3.0 file structure
            with zipfile.ZipFile(v3_file, "r") as zipf:
                project_json = zipf.read("project.json").decode("utf-8")
                v3_data = json.loads(project_json)

                assert v3_data.get("data_version") == "3.0", "Wrong version"
                assert "project_id" in v3_data, "Missing project_id in saved file"
                assert "created" in v3_data, "Missing created in saved file"
                assert "uuid" in v3_data["pages"][0], "Missing page uuid in saved file"

                print(f"   ✓ Saved file version: {v3_data.get('data_version')}")
                print(f"   ✓ All v3.0 fields present in saved file")

            print(f"\n{'=' * 60}")
            print("✅ Migration test PASSED")
            print(f"{'=' * 60}\n")
            return True

        except Exception as e:
            print(f"\n{'=' * 60}")
            print(f"❌ Migration test FAILED: {e}")
            print(f"{'=' * 60}\n")
            import traceback

            traceback.print_exc()
            return False


if __name__ == "__main__":
    success = test_migration()
    sys.exit(0 if success else 1)
