#!/usr/bin/env python3
import requests
import sys
from datetime import datetime, date
import json

class MainTechProAPITester:
    def __init__(self, base_url="https://employee-portal-134.preview.emergentagent.com"):
        self.base_url = base_url
        self.api_url = f"{base_url}/api"
        self.admin_token = None
        self.agent_token = None
        self.tests_run = 0
        self.tests_passed = 0
        
        # Test users
        self.admin_user = {
            "email": "ali.khattabi@maintech-pro.com",
            "password": "admin123"
        }
        self.agent_user = {
            "email": "omar.ouabdelmoumen@maintech-pro.com", 
            "password": "agent123"
        }

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

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

            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.text[:200]}")
                except:
                    pass
                return False, {}

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

    def test_init_data(self):
        """Initialize default users"""
        print("\n=== TESTING INITIALIZATION ===")
        success, response = self.run_test(
            "Initialize default users",
            "POST",
            "init-data",
            200
        )
        if success:
            print("   Users initialized successfully")
        return success

    def test_admin_login(self):
        """Test admin login"""
        print("\n=== TESTING ADMIN AUTHENTICATION ===")
        success, response = self.run_test(
            "Admin Login",
            "POST", 
            "auth/login",
            200,
            data=self.admin_user
        )
        if success and 'access_token' in response:
            self.admin_token = response['access_token']
            user = response.get('user', {})
            if user.get('role') == 'admin':
                print(f"   ✅ Admin role confirmed for {user.get('prenom')} {user.get('nom')}")
            else:
                print(f"   ❌ Expected admin role, got {user.get('role')}")
                return False
        return success

    def test_agent_login(self):
        """Test agent login"""
        print("\n=== TESTING AGENT AUTHENTICATION ===")
        success, response = self.run_test(
            "Agent Login",
            "POST",
            "auth/login", 
            200,
            data=self.agent_user
        )
        if success and 'access_token' in response:
            self.agent_token = response['access_token']
            user = response.get('user', {})
            if user.get('role') == 'agent':
                print(f"   ✅ Agent role confirmed for {user.get('prenom')} {user.get('nom')}")
            else:
                print(f"   ❌ Expected agent role, got {user.get('role')}")
                return False
        return success

    def test_auth_me(self):
        """Test getting current user info"""
        print("\n=== TESTING USER INFO ENDPOINTS ===")
        
        # Test admin /auth/me
        success1, admin_user = self.run_test(
            "Get admin user info",
            "GET",
            "auth/me",
            200,
            token=self.admin_token
        )
        
        # Test agent /auth/me  
        success2, agent_user = self.run_test(
            "Get agent user info", 
            "GET",
            "auth/me",
            200,
            token=self.agent_token
        )
        
        return success1 and success2

    def test_users_management(self):
        """Test user management (admin only)"""
        print("\n=== TESTING USER MANAGEMENT ===")
        
        # Get all users (admin)
        success1, users = self.run_test(
            "Get all users (admin)",
            "GET",
            "users",
            200,
            token=self.admin_token
        )
        
        # Try to get users as agent (should fail)
        success2, _ = self.run_test(
            "Get all users (agent - should fail)",
            "GET", 
            "users",
            403,
            token=self.agent_token
        )
        success2 = not success2  # We expect this to fail
        
        # Create a new user
        new_user = {
            "email": "test.user@maintech-pro.com",
            "nom": "TEST",
            "prenom": "User",
            "role": "agent",
            "password": "test123"
        }
        
        success3, created_user = self.run_test(
            "Create new user",
            "POST",
            "users",
            200,
            data=new_user,
            token=self.admin_token
        )
        
        new_user_id = None
        if success3:
            new_user_id = created_user.get('id')
            print(f"   Created user with ID: {new_user_id}")
        
        # Update the user
        success4 = True
        if new_user_id:
            update_data = {"prenom": "Updated"}
            success4, _ = self.run_test(
                "Update user",
                "PUT",
                f"users/{new_user_id}",
                200,
                data=update_data,
                token=self.admin_token
            )
        
        # Delete the user
        success5 = True
        if new_user_id:
            success5, _ = self.run_test(
                "Delete user",
                "DELETE", 
                f"users/{new_user_id}",
                200,
                token=self.admin_token
            )
        
        return success1 and success2 and success3 and success4 and success5

    def test_pointages(self):
        """Test time tracking (pointages)"""
        print("\n=== TESTING TIME TRACKING ===")
        
        # Create a pointage as agent
        today = date.today().isoformat()
        pointage_data = {
            "date": today,
            "heures_travaillees": 8.0,
            "reference_machine": "TEST-MCH-001"
        }
        
        success1, created_pointage = self.run_test(
            "Create pointage (agent)",
            "POST",
            "pointages",
            200,
            data=pointage_data,
            token=self.agent_token
        )
        
        pointage_id = None
        if success1:
            pointage_id = created_pointage.get('id')
            print(f"   Created pointage with ID: {pointage_id}")
        
        # Get agent's own pointages
        success2, agent_pointages = self.run_test(
            "Get agent pointages",
            "GET",
            "pointages", 
            200,
            token=self.agent_token
        )
        
        # Get all pointages as admin
        success3, all_pointages = self.run_test(
            "Get all pointages (admin)",
            "GET",
            "pointages",
            200,
            token=self.admin_token
        )
        
        # Update pointage
        success4 = True
        if pointage_id:
            update_data = {"heures_travaillees": 7.5}
            success4, _ = self.run_test(
                "Update pointage",
                "PUT",
                f"pointages/{pointage_id}",
                200,
                data=update_data,
                token=self.agent_token
            )
        
        # Try duplicate pointage (should fail)
        success5, _ = self.run_test(
            "Create duplicate pointage (should fail)",
            "POST",
            "pointages",
            400,
            data=pointage_data,
            token=self.agent_token
        )
        success5 = not success5  # We expect this to fail
        
        # Delete pointage
        success6 = True
        if pointage_id:
            success6, _ = self.run_test(
                "Delete pointage",
                "DELETE",
                f"pointages/{pointage_id}",
                200,
                token=self.agent_token
            )
        
        return success1 and success2 and success3 and success4 and success5 and success6

    def test_reports(self):
        """Test reports functionality"""
        print("\n=== TESTING REPORTS ===")
        
        # Get weekly report (admin)
        success1, weekly_report = self.run_test(
            "Get weekly report (admin)",
            "GET",
            "reports/summary",
            200,
            params={"period": "week"},
            token=self.admin_token
        )
        
        # Get monthly report (admin)
        success2, monthly_report = self.run_test(
            "Get monthly report (admin)",
            "GET", 
            "reports/summary",
            200,
            params={"period": "month"},
            token=self.admin_token
        )
        
        # Get agent's own report
        success3, agent_report = self.run_test(
            "Get agent report",
            "GET",
            "reports/summary",
            200,
            params={"period": "week"},
            token=self.agent_token
        )
        
        return success1 and success2 and success3

    def test_invalid_credentials(self):
        """Test invalid login credentials"""
        print("\n=== TESTING INVALID AUTHENTICATION ===")
        
        success1, _ = self.run_test(
            "Invalid email login",
            "POST",
            "auth/login",
            401,
            data={"email": "wrong@maintech-pro.com", "password": "admin123"}
        )
        success1 = not success1  # We expect this to fail
        
        success2, _ = self.run_test(
            "Invalid password login", 
            "POST",
            "auth/login",
            401,
            data={"email": "ali.khattabi@maintech-pro.com", "password": "wrongpass"}
        )
        success2 = not success2  # We expect this to fail
        
        return success1 and success2

    def test_unauthorized_access(self):
        """Test accessing protected endpoints without token"""
        print("\n=== TESTING UNAUTHORIZED ACCESS ===")
        
        success1, _ = self.run_test(
            "Access users without token",
            "GET",
            "users",
            401
        )
        success1 = not success1  # We expect this to fail
        
        success2, _ = self.run_test(
            "Access pointages without token",
            "GET", 
            "pointages",
            401
        )
        success2 = not success2  # We expect this to fail
        
        return success1 and success2

    def print_summary(self):
        """Print test results summary"""
        print("\n" + "="*60)
        print(f"📊 TEST RESULTS SUMMARY")
        print("="*60)
        print(f"Total tests run: {self.tests_run}")
        print(f"Tests passed: {self.tests_passed}")
        print(f"Tests failed: {self.tests_run - self.tests_passed}")
        print(f"Success rate: {(self.tests_passed/self.tests_run*100):.1f}%" if self.tests_run > 0 else "0%")
        
        if self.tests_passed == self.tests_run:
            print("🎉 All tests passed!")
        else:
            print(f"⚠️  {self.tests_run - self.tests_passed} test(s) failed")

def main():
    print("🚀 Starting MainTech-pro API Testing")
    print("="*60)
    
    tester = MainTechProAPITester()
    
    # Run all test suites
    test_results = []
    
    test_results.append(tester.test_init_data())
    test_results.append(tester.test_admin_login())
    test_results.append(tester.test_agent_login())
    test_results.append(tester.test_auth_me())
    test_results.append(tester.test_users_management())
    test_results.append(tester.test_pointages())
    test_results.append(tester.test_reports())
    test_results.append(tester.test_invalid_credentials())
    test_results.append(tester.test_unauthorized_access())
    
    # Print summary
    tester.print_summary()
    
    # Return appropriate exit code
    return 0 if all(test_results) else 1

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