﻿from flask import request, jsonify, render_template
from flask_login import login_user
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from werkzeug.security import check_password_hash
from datetime import datetime, timedelta

from . import auth_bp
from ...extensions import db
from ...models import User
from ...utils.validators import validate_abn, validate_email



@auth_bp.route('/register', methods=['GET', 'POST'])
def register():
    """Register a new user (worker or contractor)"""
    if request.method == 'GET':
        role = request.args.get('role', 'worker')
        return render_template('auth/register_simple.html', role=role)
    
    try:
        data = request.get_json()

        # Validate required fields
        required_fields = ['email', 'password', 'first_name', 'last_name', 'role', 
                          'phone_number', 'location', 'abn_number']

        for field in required_fields:
            if not data.get(field):
                return jsonify({'error': f'{field} is required'}), 400

        # Validate email format
        if not validate_email(data['email']):
            return jsonify({'error': 'Invalid email format'}), 400

        # Block super_admin registration (admin accounts created manually only)
        if data.get('role') == 'super_admin':
            return jsonify({'error': 'Cannot register as super admin. Contact system administrator.'}), 403
        
        # Validate role is either worker or contractor
        if data['role'] not in ['worker', 'contractor']:
            return jsonify({'error': 'Invalid role. Must be worker or contractor.'}), 400

        # Validate ABN with detailed error message
        abn_clean = data['abn_number'].replace(' ', '').replace('-', '') if data['abn_number'] else ''
        if not validate_abn(abn_clean):
            return jsonify({'error': 'Invalid ABN checksum. Please enter a valid Australian Business Number.'}), 400

        # Check if user already exists (exclude soft-deleted users)
        existing_user = User.query.filter_by(email=data['email'], is_deleted=False).first()
        if existing_user:
            return jsonify({'error': 'Email already registered'}), 400

        # Check if ABN already exists (use cleaned ABN for comparison, exclude soft-deleted users)
        existing_abn = User.query.filter_by(abn_number=abn_clean, is_deleted=False).first()
        if existing_abn:
            return jsonify({'error': 'ABN already registered'}), 400

        # Handle referral code
        referral_code = None
        if data['role'] == 'contractor':
            # Generate unique code for contractors
            import secrets
            import string
            chars = string.ascii_uppercase.replace('O', '').replace('I', '') + string.digits.replace('0', '').replace('1', '')
            
            for _ in range(10):
                referral_code = ''.join(secrets.choice(chars) for _ in range(8))
                # Only check uniqueness among contractors
                existing = User.query.filter_by(referral_code=referral_code, role='contractor').first()
                if not existing:
                    break
        elif data['role'] == 'worker' and data.get('referral_code'):
            # Store the referral code provided by worker
            referral_code = data.get('referral_code').strip().upper()

        # Create new user
        user = User(
            email=data['email'],
            first_name=data['first_name'],
            last_name=data['last_name'],
            role=data['role'],
            phone_number=data['phone_number'],
            location=data['location'],
            business_name=data.get('business_name'),
            primary_trade=data.get('primary_trade'),
            abn_number=abn_clean,
            gst_registered=data.get('gst_registered', False),
            privacy_consent=True,
            terms_accepted=True,
            terms_accepted_date=datetime.utcnow(),
            referral_code=referral_code
        )

        user.set_password(data['password'])

        db.session.add(user)
        db.session.commit()

        
        # Log the user in automatically after registration
        login_user(user, remember=True)
        
        # Create access token
        access_token = create_access_token(
            identity=user.id,
            expires_delta=timedelta(days=7)
        )

        return jsonify({
            'message': 'User registered successfully',
            'access_token': access_token,
            'user': {
                'id': user.id,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'role': user.role,
                'referral_code': user.referral_code if user.role == 'contractor' else None
            }
        }), 201

    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500


@auth_bp.route('/login', methods=['POST'])
def login():
    """Authenticate user with both JWT and Flask-Login session"""
    import logging
    from flask_login import login_user

    # Set up detailed logging
    logging.basicConfig(level=logging.DEBUG)
    logger = logging.getLogger(__name__)

    try:
        # Comprehensive debug logging following the guide
        logger.debug("=" * 60)
        logger.debug("ðŸ” LOGIN ROUTE DEBUG - SYSTEMATIC ANALYSIS")
        logger.debug("=" * 60)

        logger.debug(f"ðŸ” Method: {request.method}")
        logger.debug(f"ðŸ” Content-Type: {request.content_type}")
        logger.debug(f"ðŸ” Content-Length: {request.content_length}")
        logger.debug(f"ðŸ” Headers: {dict(request.headers)}")
        logger.debug(f"ðŸ” Raw data: {request.get_data()}")
        logger.debug(f"ðŸ” Form data: {request.form}")
        logger.debug(f"ðŸ” JSON data: {request.get_json(force=True, silent=True)}")

        # Get JSON data with error handling
        try:
            data = request.get_json(force=True)
            logger.debug(f"âœ… JSON parsed successfully: {data}")
        except Exception as json_error:
            logger.error(f"âŒ JSON parsing failed: {json_error}")
            return jsonify({'error': f'Invalid JSON data: {str(json_error)}'}), 400

        if not data:
            logger.error("âŒ No JSON data provided after parsing")
            return jsonify({'error': 'No data provided'}), 400

        # Validate required fields
        if not data.get('email') or not data.get('password'):
            return jsonify({'error': 'Email and password are required'}), 400

        # Find user by email
        user = User.query.filter_by(email=data['email']).first()

        if not user or not user.check_password(data['password']):
            return jsonify({'error': 'Invalid email or password'}), 401

        if not user.is_active:
            return jsonify({'error': 'Account is deactivated'}), 401

        # Update last login
        logger.debug("ðŸ” Updating user last login timestamp")
        user.last_login = datetime.utcnow()

        try:
            db.session.commit()
            logger.debug("âœ… Database commit successful")
        except Exception as db_error:
            logger.error(f"âŒ Database commit failed: {db_error}")
            db.session.rollback()
            return jsonify({'error': 'Database error during login'}), 500

        # CREATE BOTH JWT TOKEN AND FLASK-LOGIN SESSION
        logger.debug("ðŸ” Creating JWT access token")
        try:
            access_token = create_access_token(
                identity=user.id,
                expires_delta=timedelta(days=7)
            )
            logger.debug(f"âœ… JWT token created successfully (length: {len(access_token)})")
        except Exception as jwt_error:
            logger.error(f"âŒ JWT token creation failed: {jwt_error}")
            return jsonify({'error': 'Token generation failed'}), 500

        # API ROUTE: Only return JWT token (no Flask-Login session)
        # Flask-Login sessions are only created by web routes in app/routes.py
        logger.debug("✅ API login - returning JWT token only (no session creation)")

        # Check if worker needs onboarding
        redirect_url = f'/dashboard/{user.role}'
        if user.role == 'worker':
            needs_onboarding, missing_steps = user.needs_onboarding()
            if needs_onboarding:
                if 'profile' in missing_steps:
                    redirect_url = '/onboarding/profile'
                # Payment setup is optional - no longer redirect

        # Prepare response data
        response_data = {
            'message': 'Login successful',
            'access_token': access_token,
            'user': {
                'id': user.id,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'role': user.role,
                'total_points': user.total_points,
                'current_level': user.current_level
            },
            # IMPORTANT: Tell frontend where to redirect
            'redirect_url': redirect_url
        }

        logger.debug(f"âœ… Login successful for user: {user.email}")
        logger.debug(f"ðŸ” Response data prepared: {response_data}")
        logger.debug("=" * 60)

        return jsonify(response_data), 200

    except Exception as e:
        import traceback
        logger.error("ðŸ’¥ CRITICAL LOGIN ERROR")
        logger.error(f"ðŸ’¥ Error: {str(e)}")
        logger.error(f"ðŸ’¥ Type: {type(e).__name__}")
        logger.error(f"ðŸ’¥ Full traceback: {traceback.format_exc()}")
        logger.error("=" * 60)

        return jsonify({'error': f'Server error: {str(e)}'}), 500


@auth_bp.route('/me', methods=['GET'])
@jwt_required()
def get_current_user():
    """Get current user profile"""
    try:
        user_id = get_jwt_identity()
        user = User.query.get(user_id)

        if not user:
            return jsonify({'error': 'User not found'}), 404

        compliance_valid, compliance_issues = user.is_compliance_valid()

        return jsonify({
            'user': {
                'id': user.id,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'role': user.role,
                'business_name': user.business_name,
                'primary_trade': user.primary_trade,
                'location': user.location,
                'abn_number': user.abn_number,
                'gst_registered': user.gst_registered,
                'jobs_completed': user.jobs_completed,
                'average_rating': float(user.average_rating) if user.average_rating else 0.0,
                'total_points': user.total_points,
                'current_level': user.current_level,
                'compliance_valid': compliance_valid,
                'compliance_issues': compliance_issues,
                'referral_code': user.referral_code if user.role == 'contractor' else None
            }
        }), 200

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@auth_bp.route('/logout', methods=['POST'])
def logout():
    """Logout user from both JWT and Flask sessions"""
    from flask import session
    from flask_login import logout_user
    
    # Clear Flask-Login session (handles remember me cookies)
    logout_user()
    
    # Clear Flask session completely
    session.clear()
    
    # Clear any stored tokens on client side (handled by frontend)
    return jsonify({
        'message': 'Logout successful - cleared all sessions',
        'action': 'clear_tokens'  # Signal frontend to clear localStorage
    }), 200

