"""
Registration endpoints for multi-step user registration
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import Any
from datetime import timedelta
from uuid import UUID
import json

from app.db.session import get_db
from app.core.config import settings
from app.core.security import (
    create_access_token,
    get_password_hash,
    generate_verification_code
)
from app.models.user import User, EmailVerificationToken, UserRole, Language, Currency, Country
from app.models.company import Company, UserCompany
from app.schemas.registration import (
    EmailVerificationRequest,
    EmailVerificationConfirm, 
    UserTypeSelection,
    PersonalInfoRegistration,
    CompanyRegistration,
    RegistrationComplete,
    PendingRegistration
)
from app.schemas.auth import Token
from app.services.email_service import email_service

router = APIRouter()

# In-memory storage for pending registrations (in production, use Redis)
pending_registrations = {}


@router.post("/step1/send-verification")
async def send_email_verification(
    request: EmailVerificationRequest,
    db: Session = Depends(get_db)
) -> Any:
    """Step 1: Send email verification code"""
    
    # Check if email already exists
    existing_user = db.query(User).filter(User.email == request.email).first()
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Email already registered. Please login instead."
        )
    
    # Generate and send verification code
    success, verification_code = email_service.send_verification_email(
        db=db,
        user_id="temp",  # Temporary, will be replaced with actual user_id later
        email=request.email,
        user_name="New User"
    )
    
    if not success:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to send verification email. Please try again."
        )
    
    # Store pending registration
    pending_registrations[request.email] = PendingRegistration(
        email=request.email,
        verification_code=verification_code,
        is_verified=False
    )
    
    return {
        "message": "Verification code sent to your email. Please check your inbox.",
        "email": request.email
    }


@router.post("/step1/verify-email")
async def verify_email_code(
    request: EmailVerificationConfirm,
    db: Session = Depends(get_db)
) -> Any:
    """Step 1: Verify email with code"""
    
    # Check if pending registration exists
    if request.email not in pending_registrations:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="No verification request found for this email."
        )
    
    pending = pending_registrations[request.email]
    
    # Verify code
    if pending.verification_code != request.verification_code:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid verification code."
        )
    
    # Mark as verified
    pending.is_verified = True
    pending_registrations[request.email] = pending
    
    return {
        "message": "Email verified successfully. Please select your account type.",
        "email": request.email,
        "verified": True
    }


@router.post("/step2/select-user-type")
async def select_user_type(
    request: UserTypeSelection,
    db: Session = Depends(get_db)
) -> Any:
    """Step 2: Select user type (user or business)"""
    
    # Check if email is verified
    if request.email not in pending_registrations:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Email not found. Please start the registration process again."
        )
    
    pending = pending_registrations[request.email]
    if not pending.is_verified:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Email not verified. Please verify your email first."
        )
    
    # Update user type
    pending.user_type = request.user_type
    pending_registrations[request.email] = pending
    
    return {
        "message": f"Account type selected: {request.user_type}. Please provide your personal information.",
        "user_type": request.user_type
    }


@router.post("/step3/personal-info")
async def submit_personal_info(
    request: PersonalInfoRegistration,
    db: Session = Depends(get_db)
) -> Any:
    """Step 3: Submit personal information"""
    
    # Check if email is verified and user type selected
    if request.email not in pending_registrations:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Registration session not found. Please start again."
        )
    
    pending = pending_registrations[request.email]
    if not pending.is_verified or not pending.user_type:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Please complete previous registration steps."
        )
    
    # Validate country and language exist
    country = db.query(Country).filter(Country.country_id == request.country_id).first()
    if not country:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid country selected."
        )
    
    language = db.query(Language).filter(Language.language_id == request.language_id).first()
    if not language:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid language selected."
        )
    
    # Store personal info
    pending.personal_info = request.dict()
    pending_registrations[request.email] = pending
    
    # If user type is 'user', complete registration
    if pending.user_type == "user":
        return await complete_user_registration(request.email, db)
    
    # If business user, continue to company info
    return {
        "message": "Personal information saved. Please provide your company information.",
        "next_step": "company_info"
    }


@router.post("/step4/company-info")
async def submit_company_info(
    request: CompanyRegistration,
    db: Session = Depends(get_db)
) -> Any:
    """Step 4: Submit company information (business users only)"""
    
    # Check if previous steps completed
    if request.email not in pending_registrations:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Registration session not found. Please start again."
        )
    
    pending = pending_registrations[request.email]
    if not pending.is_verified or pending.user_type != "business" or not pending.personal_info:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Please complete previous registration steps."
        )
    
    # Validate country exists
    country = db.query(Country).filter(Country.country_id == request.country_id).first()
    if not country:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid country selected."
        )
    
    # Store company info
    pending.company_info = request.dict()
    pending_registrations[request.email] = pending
    
    # Complete business registration
    return await complete_business_registration(request.email, db)


async def complete_user_registration(email: str, db: Session) -> RegistrationComplete:
    """Complete registration for regular user"""
    
    pending = pending_registrations[email]
    personal_info = pending.personal_info
    
    try:
        # Get customer role
        customer_role = db.query(UserRole).filter(UserRole.role_name == "customer").first()
        if not customer_role:
            # Create customer role if it doesn't exist
            customer_role = UserRole(
                role_name="customer",
                description="Regular customer user"
            )
            db.add(customer_role)
            db.commit()
            db.refresh(customer_role)
        
        # Get default currency (EUR)
        default_currency = db.query(Currency).filter(Currency.currency_code == "EUR").first()
        
        # Create user
        user = User(
            email=email,
            password_hash=get_password_hash(personal_info['password']),
            first_name=personal_info['first_name'],
            last_name=personal_info['last_name'],
            phone=personal_info.get('mobile'),
            role_id=customer_role.role_id,
            preferred_language_id=personal_info['language_id'],
            preferred_currency_id=default_currency.currency_id if default_currency else None,
            is_email_verified=True,  # Already verified
            is_active=True
        )
        
        db.add(user)
        db.commit()
        db.refresh(user)
        
        # Generate login token
        access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = create_access_token(
            data={"sub": str(user.user_id)}, expires_delta=access_token_expires
        )
        
        # Clean up pending registration
        if email in pending_registrations:
            del pending_registrations[email]
        
        return RegistrationComplete(
            message="Registration completed successfully! You are now logged in.",
            user_id=user.user_id,
            needs_company_approval=False,
            login_token=access_token
        )
        
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Registration failed: {str(e)}"
        )


async def complete_business_registration(email: str, db: Session) -> RegistrationComplete:
    """Complete registration for business user"""
    
    pending = pending_registrations[email]
    personal_info = pending.personal_info
    company_info = pending.company_info
    
    try:
        # Get business owner role
        owner_role = db.query(UserRole).filter(UserRole.role_name == "company_owner").first()
        if not owner_role:
            # Create business owner role if it doesn't exist
            owner_role = UserRole(
                role_name="company_owner",
                description="Company owner with full company access"
            )
            db.add(owner_role)
            db.commit()
            db.refresh(owner_role)
        
        # Get default currency (EUR)
        default_currency = db.query(Currency).filter(Currency.currency_code == "EUR").first()
        
        # Create user
        user = User(
            email=email,
            password_hash=get_password_hash(personal_info['password']),
            first_name=personal_info['first_name'],
            last_name=personal_info['last_name'],
            phone=personal_info.get('mobile'),
            role_id=owner_role.role_id,
            preferred_language_id=personal_info['language_id'],
            preferred_currency_id=default_currency.currency_id if default_currency else None,
            is_email_verified=True,  # Already verified
            is_active=True
        )
        
        db.add(user)
        db.commit()
        db.refresh(user)
        
        # Create company
        company = Company(
            company_name=company_info['company_name'],
            address=company_info['address'],
            country_id=company_info['country_id'],
            province=company_info['province'],
            city=company_info['city'],
            postal_code=company_info['postal_code'],
            phone=company_info['phone'],
            email=email,
            vat_number=company_info.get('vat_number'),
            company_status='pending'  # Pending approval
        )
        
        db.add(company)
        db.commit()
        db.refresh(company)
        
        # Link user to company
        user_company = UserCompany(
            user_id=user.user_id,
            company_id=company.company_id,
            role='owner',
            is_active=True
        )
        
        db.add(user_company)
        db.commit()
        
        # Send notification to evaluation team
        email_service.send_company_evaluation_notification(
            company_name=company.company_name,
            company_email=email,
            contact_person=f"{personal_info['first_name']} {personal_info['last_name']}"
        )
        
        # Generate login token
        access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = create_access_token(
            data={"sub": str(user.user_id)}, expires_delta=access_token_expires
        )
        
        # Clean up pending registration
        if email in pending_registrations:
            del pending_registrations[email]
        
        return RegistrationComplete(
            message="Registration completed successfully! Your company is pending approval. You will be contacted within 1-2 working days.",
            user_id=user.user_id,
            needs_company_approval=True,
            login_token=access_token
        )
        
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Registration failed: {str(e)}"
        )


@router.get("/countries")
async def get_countries(db: Session = Depends(get_db)):
    """Get list of countries for registration form"""
    countries = db.query(Country).order_by(Country.country_name).all()
    return [
        {
            "country_id": country.country_id,
            "country_name": country.country_name,
            "country_code": country.country_code,
            "phone_code": country.phone_code
        }
        for country in countries
    ]


@router.get("/languages")
async def get_languages(db: Session = Depends(get_db)):
    """Get list of languages for registration form"""
    languages = db.query(Language).filter(Language.is_active == True).order_by(Language.language_name).all()
    return [
        {
            "language_id": language.language_id,
            "language_name": language.language_name,
            "language_code": language.language_code
        }
        for language in languages
    ]