import pytest
import os
import io
from werkzeug.datastructures import FileStorage

class TestIntegration:
    """Test integrations between different components."""
    
    def test_complete_workflow(self, logged_in_client, app):
        """Test a complete workflow from project creation to document download."""
        # 1. Create a new project
        logged_in_client.post('/projects/create', data={
            'codigo': 'WORKFLOW',
            'descripcion': 'Proyecto de flujo completo',
            'cliente': 'Cliente Integración',
            'esquema': 'TEST001',
            'destinacion': 'Pruebas de integración',
            'notas': 'Notas de proyecto de prueba'
        }, follow_redirects=True)
        
        # 2. Find the project ID
        project_id = None
        with app.app_context():
            projects_dir = os.path.join(app.config['STORAGE_PATH'], 'projects')
            project_dirs = [d for d in os.listdir(projects_dir) if 'WORKFLOW' in d]
            assert len(project_dirs) > 0
            project_dir = project_dirs[0]
            project_id = project_dir.split('_')[0].replace('@', '')
        
        assert project_id is not None
        
        # 3. Upload a document to the project
        test_file = FileStorage(
            stream=io.BytesIO(b'Content for integration test document'),
            filename='integration_doc.txt',
            content_type='text/plain',
        )
        
        response = logged_in_client.post(
            f'/projects/{project_id}/documents/upload',
            data={
                'tipo_doc': 'Documento de Prueba',
                'descripcion': 'Documento de flujo de integración',
                'file': test_file
            },
            content_type='multipart/form-data',
            follow_redirects=True
        )
        
        assert response.status_code == 200
        
        # 4. Find the document ID
        doc_id = None
        with app.app_context():
            projects_dir = os.path.join(app.config['STORAGE_PATH'], 'projects')
            for dir_name in os.listdir(projects_dir):
                if dir_name.startswith(f'@{project_id}_'):
                    project_path = os.path.join(projects_dir, dir_name)
                    docs_path = os.path.join(project_path, 'documents')
                    
                    doc_dirs = os.listdir(docs_path)
                    if doc_dirs:
                        doc_id = doc_dirs[0].split('_')[0].replace('@', '')
                        break
        
        assert doc_id is not None
        
        # 5. View document details
        response = logged_in_client.get(f'/projects/{project_id}/documents/{doc_id}')
        assert response.status_code == 200
        assert b'Documento de flujo de integraci' in response.data
        
        # 6. Upload a new version of the document
        test_file2 = FileStorage(
            stream=io.BytesIO(b'Updated content for version 2'),
            filename='integration_doc_v2.txt',
            content_type='text/plain',
        )
        
        response = logged_in_client.post(
            f'/projects/{project_id}/documents/{doc_id}/upload',
            data={
                'descripcion': 'Segunda versión del documento de integración',
                'file': test_file2
            },
            content_type='multipart/form-data',
            follow_redirects=True
        )
        
        assert response.status_code == 200
        
        # 7. Download the document
        response = logged_in_client.get(f'/projects/{project_id}/documents/{doc_id}/download/latest')
        assert response.status_code == 200
        assert b'Updated content for version 2' in response.data
        
        # 8. Download a specific version (the first one)
        response = logged_in_client.get(f'/projects/{project_id}/documents/{doc_id}/download/1')
        assert response.status_code == 200
        assert b'Content for integration test document' in response.data
    
    def test_schema_project_document_integration(self, logged_in_client, app):
        """Test integration between schemas, projects and documents."""
        # 1. Create a custom schema
        logged_in_client.post('/schemas/create', data={
            'codigo': 'CUSTOM',
            'descripcion': 'Esquema personalizado para integración',
            'documentos-0-tipo': 'pdf',
            'documentos-0-nombre': 'Informe Principal',
            'documentos-0-nivel_ver': 0,
            'documentos-0-nivel_editar': 5000,
            'documentos-1-tipo': 'txt',
            'documentos-1-nombre': 'Notas Adicionales',
            'documentos-1-nivel_ver': 0,
            'documentos-1-nivel_editar': 1000
        }, follow_redirects=True)
        
        # 2. Create a project with the custom schema
        logged_in_client.post('/projects/create', data={
            'codigo': 'PROJ_SCHEMA',
            'descripcion': 'Proyecto con esquema personalizado',
            'cliente': 'Cliente Test',
            'esquema': 'CUSTOM',
            'destinacion': 'Pruebas',
            'notas': 'Proyecto para probar integración de esquemas'
        }, follow_redirects=True)
        
        # 3. Find the project ID
        project_id = None
        with app.app_context():
            projects_dir = os.path.join(app.config['STORAGE_PATH'], 'projects')
            project_dirs = [d for d in os.listdir(projects_dir) if 'PROJ_SCHEMA' in d]
            assert len(project_dirs) > 0
            project_dir = project_dirs[0]
            project_id = project_dir.split('_')[0].replace('@', '')
        
        # 4. Verify project uses the custom schema
        response = logged_in_client.get(f'/projects/{project_id}')
        assert response.status_code == 200
        assert b'CUSTOM' in response.data
        assert b'Informe Principal' in response.data
        assert b'Notas Adicionales' in response.data
        
        # 5. Upload a document of the specified type
        test_file = FileStorage(
            stream=io.BytesIO(b'Notes content for schema integration'),
            filename='notes.txt',
            content_type='text/plain',
        )
        
        response = logged_in_client.post(
            f'/projects/{project_id}/documents/upload',
            data={
                'tipo_doc': 'Notas Adicionales',  # This should match schema document type
                'descripcion': 'Notas para prueba de esquema',
                'file': test_file
            },
            content_type='multipart/form-data',
            follow_redirects=True
        )
        
        assert response.status_code == 200
