"""
Sourcing Hub Testing - Phase 3
Tests for:
- GET /api/admin/sourcing-notes - List sourcing notes
- POST /api/admin/sourcing-notes - Create sourcing note
- DELETE /api/admin/sourcing-notes/{id} - Delete sourcing note
"""

import pytest
import requests
import os

BASE_URL = os.environ.get('REACT_APP_BACKEND_URL', '').rstrip('/')

class TestSourcingNotesAPI:
    """Sourcing Notes CRUD API tests"""
    
    @pytest.fixture(autouse=True)
    def setup(self):
        """Get admin token before each test"""
        response = requests.post(f"{BASE_URL}/api/auth/login", json={
            "username": "admin",
            "password": "queencity2024"
        })
        assert response.status_code == 200, f"Admin login failed: {response.text}"
        self.token = response.json()["token"]
        self.headers = {"Authorization": f"Bearer {self.token}"}
    
    def test_list_sourcing_notes_empty_or_array(self):
        """GET /api/admin/sourcing-notes returns array (possibly empty)"""
        response = requests.get(f"{BASE_URL}/api/admin/sourcing-notes", headers=self.headers)
        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list), "Expected array response"
        print(f"PASS: GET sourcing-notes returns array with {len(data)} items")
    
    def test_list_sourcing_notes_requires_auth(self):
        """GET /api/admin/sourcing-notes without token returns 401/403"""
        response = requests.get(f"{BASE_URL}/api/admin/sourcing-notes")
        assert response.status_code in [401, 403]
        print("PASS: Sourcing notes list requires auth")
    
    def test_create_sourcing_note_full_fields(self):
        """POST /api/admin/sourcing-notes creates note with all fields"""
        payload = {
            "title": "TEST_2020 Camry Part Out on FB Marketplace",
            "content": "Great deal on engine and transmission. Seller asking $1200 for complete drivetrain. Contact: 704-555-1234",
            "category": "partout",
            "source_url": "https://www.facebook.com/marketplace/item/123456789"
        }
        response = requests.post(f"{BASE_URL}/api/admin/sourcing-notes", json=payload, headers=self.headers)
        assert response.status_code == 200, f"Create failed: {response.text}"
        data = response.json()
        
        # Verify all fields returned
        assert "id" in data, "Response missing id"
        assert data["title"] == payload["title"]
        assert data["content"] == payload["content"]
        assert data["category"] == payload["category"]
        assert data["source_url"] == payload["source_url"]
        assert "created_at" in data
        
        print(f"PASS: Created sourcing note with id={data['id']}")
        print(f"  - title: {data['title']}")
        print(f"  - category: {data['category']}")
        
        # Cleanup - delete the note
        self.created_note_id = data["id"]
        return data["id"]
    
    def test_create_sourcing_note_minimal_fields(self):
        """POST /api/admin/sourcing-notes works with just title and content"""
        payload = {
            "title": "TEST_Quick Note",
            "content": "Found some headlights at Pull-A-Part"
        }
        response = requests.post(f"{BASE_URL}/api/admin/sourcing-notes", json=payload, headers=self.headers)
        assert response.status_code == 200, f"Create failed: {response.text}"
        data = response.json()
        
        assert "id" in data
        assert data["title"] == payload["title"]
        assert data["content"] == payload["content"]
        assert data["category"] == "general"  # Default category
        
        print(f"PASS: Created minimal note with id={data['id']}, default category='general'")
        
        # Cleanup
        requests.delete(f"{BASE_URL}/api/admin/sourcing-notes/{data['id']}", headers=self.headers)
    
    def test_create_sourcing_note_with_all_categories(self):
        """POST /api/admin/sourcing-notes accepts all valid categories"""
        categories = ["general", "partout", "junkyard", "auction", "wholesale"]
        created_ids = []
        
        for cat in categories:
            payload = {
                "title": f"TEST_Note category {cat}",
                "content": f"Testing category: {cat}",
                "category": cat
            }
            response = requests.post(f"{BASE_URL}/api/admin/sourcing-notes", json=payload, headers=self.headers)
            assert response.status_code == 200, f"Failed for category {cat}: {response.text}"
            data = response.json()
            assert data["category"] == cat
            created_ids.append(data["id"])
        
        print(f"PASS: All 5 categories accepted: {categories}")
        
        # Cleanup
        for note_id in created_ids:
            requests.delete(f"{BASE_URL}/api/admin/sourcing-notes/{note_id}", headers=self.headers)
    
    def test_create_sourcing_note_requires_auth(self):
        """POST /api/admin/sourcing-notes without token returns 401/403"""
        payload = {"title": "TEST_Unauthorized", "content": "Should fail"}
        response = requests.post(f"{BASE_URL}/api/admin/sourcing-notes", json=payload)
        assert response.status_code in [401, 403]
        print("PASS: Create sourcing note requires auth")
    
    def test_delete_sourcing_note_success(self):
        """DELETE /api/admin/sourcing-notes/{id} deletes note"""
        # First create a note
        payload = {"title": "TEST_To Delete", "content": "Will be deleted"}
        create_resp = requests.post(f"{BASE_URL}/api/admin/sourcing-notes", json=payload, headers=self.headers)
        assert create_resp.status_code == 200
        note_id = create_resp.json()["id"]
        
        # Delete it
        delete_resp = requests.delete(f"{BASE_URL}/api/admin/sourcing-notes/{note_id}", headers=self.headers)
        assert delete_resp.status_code == 200
        
        # Verify response
        data = delete_resp.json()
        assert "message" in data
        
        print(f"PASS: Deleted note {note_id}")
        
        # Verify it's gone by listing
        list_resp = requests.get(f"{BASE_URL}/api/admin/sourcing-notes", headers=self.headers)
        notes = list_resp.json()
        note_ids = [n["id"] for n in notes]
        assert note_id not in note_ids, "Deleted note still in list!"
        print("  - Verified note no longer in list")
    
    def test_delete_sourcing_note_not_found(self):
        """DELETE /api/admin/sourcing-notes/{invalid_id} returns 404"""
        response = requests.delete(f"{BASE_URL}/api/admin/sourcing-notes/invalid-note-id-12345", headers=self.headers)
        assert response.status_code == 404
        print("PASS: Delete non-existent note returns 404")
    
    def test_delete_sourcing_note_requires_auth(self):
        """DELETE /api/admin/sourcing-notes/{id} without token returns 401/403"""
        response = requests.delete(f"{BASE_URL}/api/admin/sourcing-notes/any-id")
        assert response.status_code in [401, 403]
        print("PASS: Delete sourcing note requires auth")
    
    def test_create_and_verify_persistence(self):
        """Create → GET to verify data persisted correctly"""
        # Create
        payload = {
            "title": "TEST_Persistence Check",
            "content": "Testing that data persists correctly in MongoDB",
            "category": "auction",
            "source_url": "https://copart.com/lot/123456"
        }
        create_resp = requests.post(f"{BASE_URL}/api/admin/sourcing-notes", json=payload, headers=self.headers)
        assert create_resp.status_code == 200
        created = create_resp.json()
        note_id = created["id"]
        
        # List and find it
        list_resp = requests.get(f"{BASE_URL}/api/admin/sourcing-notes", headers=self.headers)
        assert list_resp.status_code == 200
        notes = list_resp.json()
        
        found = None
        for note in notes:
            if note["id"] == note_id:
                found = note
                break
        
        assert found is not None, "Created note not found in list!"
        assert found["title"] == payload["title"]
        assert found["content"] == payload["content"]
        assert found["category"] == payload["category"]
        assert found["source_url"] == payload["source_url"]
        
        print(f"PASS: Create → GET persistence verified for note {note_id}")
        
        # Cleanup
        requests.delete(f"{BASE_URL}/api/admin/sourcing-notes/{note_id}", headers=self.headers)


class TestSourcingNotesCleanup:
    """Cleanup any TEST_ prefixed notes"""
    
    def test_cleanup_test_notes(self):
        """Remove any TEST_ prefixed notes from database"""
        # Get admin token
        response = requests.post(f"{BASE_URL}/api/auth/login", json={
            "username": "admin",
            "password": "queencity2024"
        })
        if response.status_code != 200:
            pytest.skip("Could not login for cleanup")
        
        token = response.json()["token"]
        headers = {"Authorization": f"Bearer {token}"}
        
        # List all notes
        list_resp = requests.get(f"{BASE_URL}/api/admin/sourcing-notes", headers=headers)
        if list_resp.status_code != 200:
            pytest.skip("Could not list notes for cleanup")
        
        notes = list_resp.json()
        deleted_count = 0
        
        for note in notes:
            if note.get("title", "").startswith("TEST_"):
                delete_resp = requests.delete(f"{BASE_URL}/api/admin/sourcing-notes/{note['id']}", headers=headers)
                if delete_resp.status_code == 200:
                    deleted_count += 1
        
        print(f"CLEANUP: Deleted {deleted_count} TEST_ prefixed notes")


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