"""Comprehensive seeder for all user types and test data."""

import sys
from pathlib import Path
from datetime import datetime, date, timedelta
from uuid import uuid4

# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))

from sqlalchemy.orm import Session

from app.database import SessionLocal
from app.models.admin_user import AdminRole, AdminUser
from app.models.user import User, UserType
from app.models.application import Application, ApplicationStatus
from app.models.waitlist import Waitlist
from app.utils.security import get_password_hash


# Default password for all test users
DEFAULT_PASSWORD = "password123"


def create_admin_users(db: Session):
    """Create admin users for testing."""
    print("\n=== Creating Admin Users ===")
    
    admin_users = [
        {
            "username": "admin",
            "email": "admin@proconnect-edu.online",
            "password": DEFAULT_PASSWORD,
            "role": AdminRole.ADMIN,
        },
        {
            "username": "superadmin",
            "email": "superadmin@proconnect-edu.online",
            "password": DEFAULT_PASSWORD,
            "role": AdminRole.SUPER_ADMIN,
        },
    ]
    
    created = []
    for user_data in admin_users:
        existing = db.query(AdminUser).filter(
            (AdminUser.username == user_data["username"]) | 
            (AdminUser.email == user_data["email"])
        ).first()
        
        if existing:
            print(f"  ✓ Admin user '{user_data['username']}' already exists")
            created.append(existing)
        else:
            admin_user = AdminUser(
                username=user_data["username"],
                email=user_data["email"],
                password_hash=get_password_hash(user_data["password"]),
                role=user_data["role"],
                is_active=True,
            )
            db.add(admin_user)
            db.commit()
            db.refresh(admin_user)
            print(f"  ✓ Created admin user: {user_data['username']} ({user_data['email']})")
            created.append(admin_user)
    
    return created


def create_regular_users(db: Session):
    """Create users for all user types."""
    print("\n=== Creating Regular Users ===")
    
    user_configs = [
        {
            "email": "student@proconnect-edu.online",
            "user_type": UserType.GLOBAL_UNDERGRADUATE,
            "matric_number": "POU/ACC/26/0001",
        },
        {
            "email": "lecturer@proconnect-edu.online",
            "user_type": UserType.ACADEMIC_FACULTY,
        },
        {
            "email": "registrar@proconnect-edu.online",
            "user_type": UserType.REGISTRAR_OPERATIONS,
        },
        {
            "email": "bursar@proconnect-edu.online",
            "user_type": UserType.BURSARY_CONTROL,
        },
        {
            "email": "dean@proconnect-edu.online",
            "user_type": UserType.STUDENT_DEANERY,
        },
        {
            "email": "hod@proconnect-edu.online",
            "user_type": UserType.HEAD_OF_DEPARTMENT,
        },
        {
            "email": "admissions@proconnect-edu.online",
            "user_type": UserType.ADMISSIONS_HUB,
        },
        {
            "email": "corporate@proconnect-edu.online",
            "user_type": UserType.CORPORATE_PARTNER,
        },
        {
            "email": "mentorship@proconnect-edu.online",
            "user_type": UserType.MENTORSHIP_LEAD,
        },
        {
            "email": "senate@proconnect-edu.online",
            "user_type": UserType.SENATE_ADMIN,
        },
        {
            "email": "partner@proconnect-edu.online",
            "user_type": UserType.EDUCATIONAL_PARTNER,
        },
    ]
    
    created = []
    for config in user_configs:
        existing = db.query(User).filter(User.email == config["email"]).first()
        
        if existing:
            print(f"  ✓ User '{config['email']}' already exists")
            created.append(existing)
        else:
            user = User(
                email=config["email"],
                password_hash=get_password_hash(DEFAULT_PASSWORD),
                user_type=config["user_type"],
                matric_number=config.get("matric_number"),
                is_active=True,
            )
            db.add(user)
            db.commit()
            db.refresh(user)
            print(f"  ✓ Created user: {config['email']} ({config['user_type'].value})")
            created.append(user)
    
    return created


def create_applications(db: Session):
    """Create sample applications."""
    print("\n=== Creating Sample Applications ===")
    
    applications = [
        {
            "application_id": "APP0001",
            "first_name": "David",
            "last_name": "Samuel",
            "middle_name": "Oluwaseun",
            "email": "david.samuel@example.com",
            "phone": "+2348012345678",
            "date_of_birth": date(2000, 5, 15),
            "gender": "Male",
            "state_of_origin": "Lagos",
            "lga": "Ikeja",
            "nin": "12345678901",
            "programme": "BSc Accounting and Finance",
            "status": ApplicationStatus.APPROVED,
            "matric_number": "POU/ACC/26/0001",
            "admission_date": datetime.utcnow() - timedelta(days=30),
        },
        {
            "application_id": "APP0002",
            "first_name": "Blessing",
            "last_name": "Okonkwo",
            "middle_name": "Chinwe",
            "email": "blessing.okonkwo@example.com",
            "phone": "+2348023456789",
            "date_of_birth": date(1999, 8, 22),
            "gender": "Female",
            "state_of_origin": "Anambra",
            "lga": "Awka",
            "nin": "23456789012",
            "programme": "BSc Business Administration",
            "status": ApplicationStatus.PENDING,
        },
        {
            "application_id": "APP0003",
            "first_name": "Emeka",
            "last_name": "Nwankwo",
            "middle_name": "Chukwuemeka",
            "email": "emeka.nwankwo@example.com",
            "phone": "+2348034567890",
            "date_of_birth": date(2001, 3, 10),
            "gender": "Male",
            "state_of_origin": "Enugu",
            "lga": "Enugu North",
            "nin": "34567890123",
            "programme": "BSc Computer Science",
            "status": ApplicationStatus.APPROVED,
            "matric_number": "POU/CS/26/0001",
            "admission_date": datetime.utcnow() - timedelta(days=15),
        },
        {
            "application_id": "APP0004",
            "first_name": "Amina",
            "last_name": "Ibrahim",
            "middle_name": "Fatima",
            "email": "amina.ibrahim@example.com",
            "phone": "+2348045678901",
            "date_of_birth": date(2002, 11, 5),
            "gender": "Female",
            "state_of_origin": "Kano",
            "lga": "Kano Municipal",
            "nin": "45678901234",
            "programme": "BSc Economics",
            "status": ApplicationStatus.REJECTED,
            "rejection_note": "Incomplete documentation",
        },
        {
            "application_id": "APP0005",
            "first_name": "Tunde",
            "last_name": "Adebayo",
            "middle_name": "Oluwaseyi",
            "email": "tunde.adebayo@example.com",
            "phone": "+2348056789012",
            "date_of_birth": date(2000, 7, 18),
            "gender": "Male",
            "state_of_origin": "Oyo",
            "lga": "Ibadan North",
            "nin": "56789012345",
            "programme": "BSc Accounting and Finance",
            "status": ApplicationStatus.PENDING,
        },
    ]
    
    created = []
    for app_data in applications:
        existing = db.query(Application).filter(
            Application.application_id == app_data["application_id"]
        ).first()
        
        if existing:
            print(f"  ✓ Application '{app_data['application_id']}' already exists")
            created.append(existing)
        else:
            application = Application(**app_data)
            db.add(application)
            db.commit()
            db.refresh(application)
            print(f"  ✓ Created application: {app_data['application_id']} - {app_data['first_name']} {app_data['last_name']}")
            created.append(application)
    
    return created


def create_waitlist_entries(db: Session):
    """Create sample waitlist entries."""
    print("\n=== Creating Waitlist Entries ===")
    
    waitlist_entries = [
        {
            "full_name": "John Doe",
            "gender": "Male",
            "email": "john.doe@example.com",
            "phone": "+2348067890123",
            "whatsapp_phone": "+2348067890123",
            "date_of_birth": date(1998, 3, 15),
            "age": "26",
            "state": "Lagos",
            "lga": "Ikeja",
            "qualification": "WAEC",
            "status": "waiting",
        },
        {
            "full_name": "Jane Smith",
            "gender": "Female",
            "email": "jane.smith@example.com",
            "phone": "+2348078901234",
            "whatsapp_phone": "+2348078901234",
            "date_of_birth": date(1999, 7, 22),
            "age": "25",
            "state": "Abuja",
            "lga": "Garki",
            "qualification": "NECO",
            "status": "invited",
            "invitation_sent": True,
            "invitation_sent_at": datetime.utcnow() - timedelta(days=5),
        },
        {
            "full_name": "Michael Johnson",
            "gender": "Male",
            "email": "michael.johnson@example.com",
            "phone": "+2348089012345",
            "whatsapp_phone": "+2348089012345",
            "date_of_birth": date(2000, 11, 8),
            "age": "24",
            "state": "Rivers",
            "lga": "Port Harcourt",
            "qualification": "WAEC",
            "status": "invited",
            "invitation_sent": True,
            "invitation_sent_at": datetime.utcnow() - timedelta(days=10),
            "followup_count": 1,
            "last_followup_at": datetime.utcnow() - timedelta(days=3),
        },
        {
            "full_name": "Sarah Williams",
            "gender": "Female",
            "email": "sarah.williams@example.com",
            "phone": "+2348090123456",
            "whatsapp_phone": "+2348090123456",
            "date_of_birth": date(1997, 4, 12),
            "age": "27",
            "state": "Kaduna",
            "lga": "Kaduna North",
            "qualification": "WAEC",
            "status": "converted",
            "invitation_sent": True,
            "invitation_sent_at": datetime.utcnow() - timedelta(days=20),
            "followup_count": 2,
            "last_followup_at": datetime.utcnow() - timedelta(days=5),
            "has_applied": True,
        },
    ]
    
    created = []
    for entry_data in waitlist_entries:
        existing = db.query(Waitlist).filter(Waitlist.email == entry_data["email"]).first()
        
        if existing:
            print(f"  ✓ Waitlist entry for '{entry_data['email']}' already exists")
            created.append(existing)
        else:
            waitlist = Waitlist(**entry_data)
            db.add(waitlist)
            db.commit()
            db.refresh(waitlist)
            print(f"  ✓ Created waitlist entry: {entry_data['full_name']} ({entry_data['email']})")
            created.append(waitlist)
    
    return created


def link_student_to_application(db: Session):
    """Link student user to their application."""
    print("\n=== Linking Student to Application ===")
    
    student = db.query(User).filter(
        User.email == "student@proconnect-edu.online"
    ).first()
    
    application = db.query(Application).filter(
        Application.application_id == "APP0001"
    ).first()
    
    if student and application:
        student.application_id = application.application_id
        db.commit()
        print(f"  ✓ Linked student {student.email} to application {application.application_id}")
    else:
        print(f"  ⚠ Could not link student to application (student or application not found)")


def main():
    """Main seeder function."""
    print("=" * 60)
    print("POU Comprehensive User Seeder")
    print("=" * 60)
    
    db: Session = SessionLocal()
    try:
        # Create all user types
        admin_users = create_admin_users(db)
        regular_users = create_regular_users(db)
        applications = create_applications(db)
        waitlist_entries = create_waitlist_entries(db)
        link_student_to_application(db)
        
        print("\n" + "=" * 60)
        print("Seeder Summary")
        print("=" * 60)
        print(f"Admin Users: {len(admin_users)}")
        print(f"Regular Users: {len(regular_users)}")
        print(f"Applications: {len(applications)}")
        print(f"Waitlist Entries: {len(waitlist_entries)}")
        
        print("\n" + "=" * 60)
        print("Test Credentials")
        print("=" * 60)
        print("\nAdmin Users:")
        print("  - admin@proconnect-edu.online / password123 (Admin)")
        print("  - superadmin@proconnect-edu.online / password123 (Super Admin)")
        
        print("\nRegular Users (all use password: password123):")
        print("  - student@proconnect-edu.online (Global Undergraduate)")
        print("  - lecturer@proconnect-edu.online (Academic Faculty)")
        print("  - registrar@proconnect-edu.online (Registrar Operations)")
        print("  - bursar@proconnect-edu.online (Bursary Control)")
        print("  - dean@proconnect-edu.online (Student Deanery)")
        print("  - hod@proconnect-edu.online (Head of Department)")
        print("  - admissions@proconnect-edu.online (Admissions Hub)")
        print("  - corporate@proconnect-edu.online (Corporate Partner)")
        print("  - mentorship@proconnect-edu.online (Mentorship Lead)")
        print("  - senate@proconnect-edu.online (Senate Admin)")
        print("  - partner@proconnect-edu.online (Educational Partner)")
        
        print("\n" + "=" * 60)
        print("Seeder completed successfully!")
        print("=" * 60)
        
    except Exception as e:
        db.rollback()
        print(f"\n❌ Error running seeder: {e}")
        import traceback
        traceback.print_exc()
        raise
    finally:
        db.close()


if __name__ == "__main__":
    main()
