"""
Test script for updating custom task statuses
Tests Requirements: 2.1, 2.2, 2.3, 5.2
"""

import requests
import json

BASE_URL = "http://localhost:8000"

def login_as_admin():
    """Login as admin user"""
    response = requests.post(
        f"{BASE_URL}/auth/login",
        json={
            "email": "admin@vfx.com",
            "password": "admin123"
        }
    )
    if response.status_code == 200:
        return response.json()["access_token"]
    else:
        print(f"Login failed: {response.status_code}")
        print(response.text)
        return None

def get_all_task_statuses(token, project_id):
    """Get all task statuses for a project"""
    response = requests.get(
        f"{BASE_URL}/projects/{project_id}/task-statuses",
        headers={"Authorization": f"Bearer {token}"}
    )
    if response.status_code == 200:
        return response.json()
    else:
        print(f"Failed to get task statuses: {response.status_code}")
        print(response.text)
        return None

def create_custom_status(token, project_id, name, color=None):
    """Create a custom task status"""
    data = {"name": name}
    if color:
        data["color"] = color
    
    response = requests.post(
        f"{BASE_URL}/projects/{project_id}/task-statuses",
        headers={"Authorization": f"Bearer {token}"},
        json=data
    )
    if response.status_code == 201:
        return response.json()
    else:
        print(f"Failed to create status: {response.status_code}")
        print(response.text)
        return None

def update_custom_status(token, project_id, status_id, name=None, color=None, is_default=None):
    """Update a custom task status"""
    data = {}
    if name is not None:
        data["name"] = name
    if color is not None:
        data["color"] = color
    if is_default is not None:
        data["is_default"] = is_default
    
    response = requests.put(
        f"{BASE_URL}/projects/{project_id}/task-statuses/{status_id}",
        headers={"Authorization": f"Bearer {token}"},
        json=data
    )
    if response.status_code == 200:
        return response.json()
    else:
        print(f"Failed to update status: {response.status_code}")
        print(response.text)
        return None

def main():
    print("=" * 80)
    print("Testing Custom Task Status Update Endpoint")
    print("=" * 80)
    
    # Login
    print("\n1. Logging in as admin...")
    token = login_as_admin()
    if not token:
        print("❌ Failed to login")
        return
    print("✅ Login successful")
    
    # Use project ID 1 (should exist from setup)
    project_id = 1
    
    # Get initial statuses
    print(f"\n2. Getting initial task statuses for project {project_id}...")
    initial_statuses = get_all_task_statuses(token, project_id)
    if not initial_statuses:
        print("❌ Failed to get initial statuses")
        return
    print(f"✅ Found {len(initial_statuses['statuses'])} custom statuses")
    print(f"   System statuses: {len(initial_statuses['system_statuses'])}")
    
    # Create a test status
    print("\n3. Creating a test custom status...")
    create_result = create_custom_status(token, project_id, "Test Status", "#FF5733")
    if not create_result:
        print("❌ Failed to create test status")
        return
    
    created_status = create_result['status']
    status_id = created_status['id']
    print(f"✅ Created status: {created_status['name']} (ID: {status_id})")
    print(f"   Color: {created_status['color']}")
    print(f"   Order: {created_status['order']}")
    print(f"   Is Default: {created_status['is_default']}")
    
    # Test 1: Update status name (Requirement 2.1)
    print("\n4. Test 1: Updating status name...")
    update_result = update_custom_status(token, project_id, status_id, name="Updated Test Status")
    if not update_result:
        print("❌ Failed to update status name")
        return
    
    updated_status = update_result['status']
    if updated_status['name'] == "Updated Test Status":
        print(f"✅ Status name updated successfully: {updated_status['name']}")
    else:
        print(f"❌ Status name not updated correctly: {updated_status['name']}")
        return
    
    # Test 2: Update status color (Requirement 2.2)
    print("\n5. Test 2: Updating status color...")
    update_result = update_custom_status(token, project_id, status_id, color="#00FF00")
    if not update_result:
        print("❌ Failed to update status color")
        return
    
    updated_status = update_result['status']
    if updated_status['color'] == "#00FF00":
        print(f"✅ Status color updated successfully: {updated_status['color']}")
    else:
        print(f"❌ Status color not updated correctly: {updated_status['color']}")
        return
    
    # Test 3: Update both name and color (Requirement 2.1, 2.2)
    print("\n6. Test 3: Updating both name and color...")
    update_result = update_custom_status(
        token, project_id, status_id, 
        name="Final Test Status", 
        color="#0000FF"
    )
    if not update_result:
        print("❌ Failed to update status name and color")
        return
    
    updated_status = update_result['status']
    if updated_status['name'] == "Final Test Status" and updated_status['color'] == "#0000FF":
        print(f"✅ Status name and color updated successfully")
        print(f"   Name: {updated_status['name']}")
        print(f"   Color: {updated_status['color']}")
    else:
        print(f"❌ Status not updated correctly")
        return
    
    # Test 4: Validate name uniqueness (Requirement 2.4)
    print("\n7. Test 4: Testing name uniqueness validation...")
    # Create another status
    create_result2 = create_custom_status(token, project_id, "Another Status", "#FFFF00")
    if not create_result2:
        print("❌ Failed to create second test status")
        return
    
    status_id2 = create_result2['status']['id']
    print(f"✅ Created second status: {create_result2['status']['name']}")
    
    # Try to update first status with the name of the second status
    print("   Attempting to update with duplicate name...")
    update_result = update_custom_status(token, project_id, status_id, name="Another Status")
    if update_result is None:
        print("✅ Duplicate name correctly rejected")
    else:
        print("❌ Duplicate name was not rejected")
        return
    
    # Test 5: Try to use system status name (Requirement 2.4)
    print("\n8. Test 5: Testing system status name conflict...")
    update_result = update_custom_status(token, project_id, status_id, name="In Progress")
    if update_result is None:
        print("✅ System status name correctly rejected")
    else:
        print("❌ System status name was not rejected")
        return
    
    # Test 6: Set as default status (Requirement 2.3, 5.2)
    print("\n9. Test 6: Setting status as default...")
    update_result = update_custom_status(token, project_id, status_id, is_default=True)
    if not update_result:
        print("❌ Failed to set status as default")
        return
    
    updated_status = update_result['status']
    all_statuses = update_result['all_statuses']
    
    if updated_status['is_default']:
        print(f"✅ Status set as default successfully")
        print(f"   Default status ID: {all_statuses['default_status_id']}")
        
        # Verify only one default status exists
        default_count = sum(1 for s in all_statuses['statuses'] if s['is_default'])
        if default_count == 1:
            print(f"✅ Only one default status exists")
        else:
            print(f"❌ Multiple default statuses found: {default_count}")
            return
    else:
        print(f"❌ Status not set as default")
        return
    
    # Test 7: Set another status as default (should unset previous default)
    print("\n10. Test 7: Setting another status as default (should unset previous)...")
    update_result = update_custom_status(token, project_id, status_id2, is_default=True)
    if not update_result:
        print("❌ Failed to set second status as default")
        return
    
    all_statuses = update_result['all_statuses']
    
    # Verify only one default status exists
    default_count = sum(1 for s in all_statuses['statuses'] if s['is_default'])
    if default_count == 1:
        print(f"✅ Only one default status exists after changing default")
        print(f"   New default status ID: {all_statuses['default_status_id']}")
        
        # Verify the first status is no longer default
        first_status = next((s for s in all_statuses['statuses'] if s['id'] == status_id), None)
        if first_status and not first_status['is_default']:
            print(f"✅ Previous default status correctly unset")
        else:
            print(f"❌ Previous default status not unset")
            return
    else:
        print(f"❌ Multiple default statuses found: {default_count}")
        return
    
    # Test 8: Unset default status
    print("\n11. Test 8: Unsetting default status...")
    update_result = update_custom_status(token, project_id, status_id2, is_default=False)
    if not update_result:
        print("❌ Failed to unset default status")
        return
    
    updated_status = update_result['status']
    if not updated_status['is_default']:
        print(f"✅ Default status unset successfully")
    else:
        print(f"❌ Default status not unset")
        return
    
    # Test 9: Update non-existent status
    print("\n12. Test 9: Testing update of non-existent status...")
    update_result = update_custom_status(token, project_id, "nonexistent_id", name="Test")
    if update_result is None:
        print("✅ Non-existent status correctly rejected")
    else:
        print("❌ Non-existent status was not rejected")
        return
    
    # Test 10: Verify flag_modified works (JSON column update)
    print("\n13. Test 10: Verifying JSON column updates persist...")
    # Get statuses again to verify changes persisted
    final_statuses = get_all_task_statuses(token, project_id)
    if not final_statuses:
        print("❌ Failed to get final statuses")
        return
    
    # Find our updated status
    final_status = next((s for s in final_statuses['statuses'] if s['id'] == status_id), None)
    if final_status:
        if final_status['name'] == "Final Test Status" and final_status['color'] == "#0000FF":
            print(f"✅ Changes persisted correctly in database")
            print(f"   Name: {final_status['name']}")
            print(f"   Color: {final_status['color']}")
        else:
            print(f"❌ Changes did not persist correctly")
            return
    else:
        print(f"❌ Updated status not found in final list")
        return
    
    print("\n" + "=" * 80)
    print("✅ ALL TESTS PASSED!")
    print("=" * 80)
    print("\nSummary:")
    print("  ✅ Status name update works (Requirement 2.1)")
    print("  ✅ Status color update works (Requirement 2.2)")
    print("  ✅ Default status management works (Requirement 2.3, 5.2)")
    print("  ✅ Name uniqueness validation works (Requirement 2.4)")
    print("  ✅ System status name conflict detection works")
    print("  ✅ Only one default status at a time (Requirement 5.2)")
    print("  ✅ flag_modified ensures JSON column updates persist")
    print("  ✅ Non-existent status handling works")

if __name__ == "__main__":
    main()
