import pytest
from unittest.mock import MagicMock, patch
from io import BytesIO
from openpyxl import Workbook
from app.services.agent_assets import AgentAssetService
from app.schemas.agent_asset import AgentAssetOnlyOfficeCallbackWrite

def test_onlyoffice_callback_generates_summary_note():
    # Setup mock DB and repository
    db = MagicMock()
    service = AgentAssetService(db)
    service.repository = MagicMock()
    service.spreadsheet_manager = MagicMock()
    service._ensure_ready = MagicMock()
    
    # Mock asset and metadata
    asset = MagicMock()
    asset.id = "test-asset"
    asset.name = "测试规则"
    service._require_spreadsheet_rule = MagicMock(return_value=asset)
    service._resolve_working_version = MagicMock(return_value="v1")
    
    base_meta = MagicMock()
    base_meta.file_name = "test.xlsx"
    base_meta.storage_key = "old-key"
    base_meta.checksum = "old-checksum"
    service._resolve_spreadsheet_version_meta = MagicMock(return_value=("v1", base_meta))
    
    # Create base workbook
    base_wb = Workbook()
    base_ws = base_wb.active
    base_ws["A1"] = "old value"
    
    # Mock loading base workbook
    service._load_spreadsheet_for_compare = MagicMock(return_value=base_wb)
    service.spreadsheet_manager.resolve_storage_path = MagicMock()
    
    # Create new content (modified)
    new_wb = Workbook()
    new_ws = new_wb.active
    new_ws["A1"] = "new value"  # 1 cell changed
    new_ws["B2"] = "added"      # 1 more cell changed
    
    # Mock URL open to return new content
    new_content_bio = BytesIO()
    new_wb.save(new_content_bio)
    new_content = new_content_bio.getvalue()
    
    with patch("app.services.agent_assets.urlopen") as mock_urlopen:
        mock_response = MagicMock()
        mock_response.read.return_value = new_content
        mock_response.__enter__.return_value = mock_response
        mock_urlopen.return_value = mock_response
        
        # Mock upload_rule_spreadsheet
        service.upload_rule_spreadsheet = MagicMock()
        
        # Execute callback handler
        payload = {
            "status": 2,
            "url": "http://onlyoffice/download",
            "users": ["test_user"]
        }
        
        service.handle_rule_spreadsheet_onlyoffice_callback(
            "test-asset",
            version="v1",
            payload=payload
        )
        
        # Verify upload_rule_spreadsheet was called with correct change_note
        service.upload_rule_spreadsheet.assert_called_once()
        call_args = service.upload_rule_spreadsheet.call_args[1]
        assert "涉及 1 个 Sheet，共 2 处改动" in call_args["change_note"]
        assert call_args["actor"] == "test_user"

if __name__ == "__main__":
    pytest.main([__file__])
