import requests
import sys
import json
from datetime import datetime

class GuiaDespachoTester:
    def __init__(self, base_url="https://doc-manager-111.preview.emergentagent.com"):
        self.base_url = base_url
        self.tokens = {}  # Store tokens for different users
        self.tests_run = 0
        self.tests_passed = 0
        self.empresa_id = None
        self.created_guia_id = None

    def run_test(self, name, method, endpoint, expected_status, data=None, token=None):
        """Run a single API test"""
        url = f"{self.base_url}/api/{endpoint}"
        headers = {'Content-Type': 'application/json'}
        if token:
            headers['Authorization'] = f'Bearer {token}'

        self.tests_run += 1
        print(f"\n🔍 Testing {name}...")
        print(f"   URL: {url}")
        
        try:
            if method == 'GET':
                response = requests.get(url, headers=headers, timeout=10)
            elif method == 'POST':
                response = requests.post(url, json=data, headers=headers, timeout=10)
            elif method == 'PUT':
                response = requests.put(url, json=data, headers=headers, timeout=10)

            success = response.status_code == expected_status
            if success:
                self.tests_passed += 1
                print(f"✅ Passed - Status: {response.status_code}")
                try:
                    return success, response.json()
                except:
                    return success, {}
            else:
                print(f"❌ Failed - Expected {expected_status}, got {response.status_code}")
                try:
                    print(f"   Response: {response.json()}")
                except:
                    print(f"   Response: {response.text}")
                return False, {}

        except Exception as e:
            print(f"❌ Failed - Error: {str(e)}")
            return False, {}

    def test_seed_data(self):
        """Test seed data creation"""
        success, response = self.run_test(
            "Seed Demo Data",
            "POST",
            "seed",
            200
        )
        if success and response.get('empresa_id'):
            self.empresa_id = response['empresa_id']
            print(f"   Empresa ID: {self.empresa_id}")
        return success

    def test_login(self, email, password, role):
        """Test login for different roles"""
        success, response = self.run_test(
            f"Login {role}",
            "POST",
            "auth/login",
            200,
            data={"email": email, "password": password}
        )
        if success and 'access_token' in response:
            self.tokens[role] = response['access_token']
            print(f"   Token obtained for {role}")
            return True
        return False

    def test_get_stats(self, role):
        """Test stats endpoint"""
        token = self.tokens.get(role)
        if not token:
            print(f"❌ No token for {role}")
            return False
        
        success, response = self.run_test(
            f"Get Stats ({role})",
            "GET",
            "stats",
            200,
            token=token
        )
        if success:
            print(f"   Stats: {response}")
        return success

    def test_get_vehiculos(self, role):
        """Test vehicle list endpoint"""
        token = self.tokens.get(role)
        if not token:
            print(f"❌ No token for {role}")
            return False
        
        success, response = self.run_test(
            f"Get Vehiculos ({role})",
            "GET",
            "vehiculos",
            200,
            token=token
        )
        if success:
            print(f"   Found {len(response)} vehicles")
        return success

    def test_buscar_vehiculo(self, patente):
        """Test vehicle search endpoint"""
        token = self.tokens.get('solicitante')
        if not token:
            print("❌ No token for solicitante")
            return False
        
        success, response = self.run_test(
            f"Search Vehicle '{patente}'",
            "GET",
            f"vehiculos/buscar/{patente}",
            200,
            token=token
        )
        return success

    def test_crear_guia(self):
        """Test guide creation"""
        token = self.tokens.get('solicitante')
        if not token:
            print("❌ No token for solicitante")
            return False
        
        guide_data = {
            "tipo": "salida",
            "patente": "ABCD12",
            "rut_destino": "96.000.000-0",
            "descripcion": "Guía de prueba automática",
            "items": [
                {
                    "descripcion": "Material de prueba",
                    "cantidad": "10",
                    "unidad": "UN"
                }
            ]
        }
        
        success, response = self.run_test(
            "Create Guide (Solicitante)",
            "POST",
            "documentos",
            200,
            data=guide_data,
            token=token
        )
        if success and response.get('id'):
            self.created_guia_id = response['id']
            print(f"   Created guide: {response.get('folio')}")
        return success

    def test_get_guias_pendientes(self):
        """Test getting pending guides for manager"""
        token = self.tokens.get('gerente')
        if not token:
            print("❌ No token for gerente")
            return False
        
        success, response = self.run_test(
            "Get Pending Guides (Gerente)",
            "GET",
            "documentos?estado=pendiente",
            200,
            token=token
        )
        if success:
            print(f"   Found {len(response)} pending guides")
        return success

    def test_aprobar_guia(self):
        """Test guide approval"""
        if not self.created_guia_id:
            print("❌ No guide to approve")
            return False
        
        token = self.tokens.get('gerente')
        if not token:
            print("❌ No token for gerente")
            return False
        
        approval_data = {
            "documento_id": self.created_guia_id,
            "estado": "autorizado",
            "observacion": "Aprobado por pruebas automáticas"
        }
        
        success, response = self.run_test(
            "Approve Guide (Gerente)",
            "POST",
            f"documentos/{self.created_guia_id}/aprobar",
            200,
            data=approval_data,
            token=token
        )
        return success

    def test_get_guias_autorizadas(self):
        """Test getting authorized guides for security"""
        token = self.tokens.get('seguridad')
        if not token:
            print("❌ No token for seguridad")
            return False
        
        success, response = self.run_test(
            "Get Authorized Guides (Seguridad)",
            "GET",
            "documentos?estado=autorizado",
            200,
            token=token
        )
        if success:
            print(f"   Found {len(response)} authorized guides")
        return success

    def test_despachar_guia(self):
        """Test guide dispatch"""
        if not self.created_guia_id:
            print("❌ No guide to dispatch")
            return False
        
        token = self.tokens.get('seguridad')
        if not token:
            print("❌ No token for seguridad")
            return False
        
        dispatch_data = {
            "documento_id": self.created_guia_id,
            "estado": "despachado",
            "observacion": "Despachado por pruebas automáticas"
        }
        
        success, response = self.run_test(
            "Dispatch Guide (Seguridad)",
            "POST",
            f"documentos/{self.created_guia_id}/despachar",
            200,
            data=dispatch_data,
            token=token
        )
        return success

    def test_reject_at_exit(self):
        """Test rejection at exit point with motives and observation"""
        # First create a new guide for rejection test
        token = self.tokens.get('solicitante')
        guide_data = {
            "tipo": "salida",
            "patente": "WXYZ98",
            "rut_destino": "91.000.000-6",
            "descripcion": "Guía para probar rechazo",
            "items": []
        }
        
        success, response = self.run_test(
            "Create Guide for Rejection Test",
            "POST",
            "documentos",
            200,
            data=guide_data,
            token=token
        )
        
        if not success:
            return False
        
        rejection_guide_id = response['id']
        
        # Approve it first
        token = self.tokens.get('gerente')
        approval_data = {
            "documento_id": rejection_guide_id,
            "estado": "autorizado",
            "observacion": "Aprobado para prueba de rechazo"
        }
        
        success, _ = self.run_test(
            "Approve Guide for Rejection Test",
            "POST",
            f"documentos/{rejection_guide_id}/aprobar",
            200,
            data=approval_data,
            token=token
        )
        
        if not success:
            return False
        
        # Now reject at exit point
        token = self.tokens.get('seguridad')
        rejection_data = {
            "documento_id": rejection_guide_id,
            "estado": "rechazado",
            "motivos_rechazo": ["Sello roto", "Documentación incorrecta"],
            "observacion": "Rechazo por pruebas automáticas - documentos no coinciden"
        }
        
        success, response = self.run_test(
            "Reject at Exit (Seguridad)",
            "POST",
            f"documentos/{rejection_guide_id}/despachar",
            200,
            data=rejection_data,
            token=token
        )
        return success

def main():
    print("🚛 Iniciando pruebas del Sistema de Guías de Despacho...")
    tester = GuiaDespachoTester()
    
    # Test credentials from the seed data
    demo_users = [
        ("admin@demo.com", "admin123", "admin"),
        ("solicitante@demo.com", "solicitante123", "solicitante"),
        ("gerente@demo.com", "gerente123", "gerente"),
        ("seguridad@demo.com", "seguridad123", "seguridad"),
    ]
    
    # 1. Create seed data
    if not tester.test_seed_data():
        print("\n❌ Seed data creation failed, stopping tests")
        return 1
    
    # 2. Test login for all roles
    for email, password, role in demo_users:
        if not tester.test_login(email, password, role):
            print(f"\n❌ Login failed for {role}, stopping tests")
            return 1
    
    # 3. Test stats endpoint
    tester.test_get_stats('admin')
    
    # 4. Test vehicle operations
    tester.test_get_vehiculos('solicitante')
    tester.test_buscar_vehiculo('ABCD')
    
    # 5. Test guide workflow
    if not tester.test_crear_guia():
        print("\n❌ Guide creation failed")
        return 1
    
    # 6. Test manager approval workflow
    tester.test_get_guias_pendientes()
    if not tester.test_aprobar_guia():
        print("\n❌ Guide approval failed")
        return 1
    
    # 7. Test security dispatch workflow
    tester.test_get_guias_autorizadas()
    if not tester.test_despachar_guia():
        print("\n❌ Guide dispatch failed")
        return 1
    
    # 8. Test rejection workflow (requires motives and observation)
    tester.test_reject_at_exit()
    
    # Print final results
    print(f"\n📊 Resultados finales:")
    print(f"   Pruebas ejecutadas: {tester.tests_run}")
    print(f"   Pruebas exitosas: {tester.tests_passed}")
    print(f"   Tasa de éxito: {(tester.tests_passed/tester.tests_run)*100:.1f}%")
    
    success_rate = (tester.tests_passed / tester.tests_run) * 100
    if success_rate >= 80:
        print("\n✅ Sistema funcionando correctamente")
        return 0
    else:
        print(f"\n⚠️ Sistema con problemas - Tasa de éxito: {success_rate:.1f}%")
        return 1

if __name__ == "__main__":
    sys.exit(main())