from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify
import requests
from flask_login import login_user, logout_user, login_required, current_user
from app.extensions import db, limiter, mail
from app.models.user import User
from app.i18n import flash_i18n
from datetime import datetime

auth_bp = Blueprint("auth", __name__, url_prefix="/auth")

# Import enterprise registration routes
from app.routes import auth_register_flow  # noqa: F401


@auth_bp.route("/register", methods=["GET", "POST"])
@limiter.limit("10 per hour")
def register():
    if current_user.is_authenticated:
        return redirect(url_for("dashboard.index"))

    # Check if registration is enabled
    from app.models.features import SystemSetting
    if not SystemSetting.get("registration_enabled", default=True):
        return render_template("auth/registration_disabled.html")

    if request.method == "POST":
        name = request.form.get("name", "").strip()
        email = request.form.get("email", "").strip().lower()
        password = request.form.get("password", "")
        if not name or not email or not password:
            flash_i18n("flash.all_fields_required", "error")
            return render_template("auth/register.html")
        if len(password) < 8:
            flash_i18n("flash.password_too_short", "error")
            return render_template("auth/register.html")
        if User.query.filter_by(email=email).first():
            flash_i18n("flash.email_exists", "error")
            return render_template("auth/register.html")
        account_type = request.form.get("account_type", "entrepreneur").strip()
        company_name = request.form.get("company_name", "").strip() or None
        organization_id = request.form.get("organization_id")
        interests = request.form.getlist("interests")
        user = User(name=name, email=email, account_type=account_type,
                    company_name=company_name,
                    organization_id=organization_id,
                    interests_json=interests if interests else None)

        # Handle organization selection
        if organization_id:
            try:
                user.organization_id = int(organization_id)
            except (ValueError, TypeError):
                pass

        user.set_password(password)
        db.session.add(user)
        db.session.commit()
        # Auto-create FactoryPartner record for factory accounts
        if account_type == "factory" and company_name:
            from app.models.services import FactoryPartner
            fp = FactoryPartner(
                name=company_name, name_ar=company_name,
                user_id=user.id, sectors_json=interests,
                is_verified=False, is_active=True,
            )
            db.session.add(fp)
            user.factory_partner_id = fp.id
            db.session.commit()
        _send_verification_email(user)
        login_user(user)
        flash_i18n("flash.register_success", "success")
        return redirect(url_for("dashboard.index"))
    return render_template("auth/register.html")


@auth_bp.route("/search-organizations")
@limiter.limit("100 per hour")
def search_organizations():
    """Search organizations for autocomplete in registration form."""
    from app.models.organization import Organization

    q = request.args.get("q", "").strip()
    query = Organization.query.filter(Organization.deleted_at == None, Organization.is_active == True)

    if q:
        query = query.filter(
            Organization.name.ilike(f"%{q}%") |
            Organization.name_ar.ilike(f"%{q}%")
        )

    organizations = query.order_by(Organization.name).limit(20).all()

    return jsonify({
        "organizations": [
            {
                "id": org.id,
                "name": org.name_ar or org.name
            }
            for org in organizations
        ]
    })


@auth_bp.route("/login", methods=["GET", "POST"])
@limiter.limit("20 per hour")
def login():
    if current_user.is_authenticated:
        return redirect(url_for("dashboard.index"))
    if request.method == "POST":
        email = request.form.get("email", "").strip().lower()
        password = request.form.get("password", "")
        user = User.query.filter_by(email=email).first()

        # Get client info for logging
        ip_address = request.headers.get("X-Forwarded-For", request.remote_addr)
        user_agent = request.headers.get("User-Agent", "")[:500]

        if user and not user.password_hash:
            # User registered with Google only, suggest Google login
            flash_i18n("flash.use_google_login", "error")
            return render_template("auth/login.html")

        if user and user.check_password(password):
            if user.two_factor_enabled:
                from flask import session
                session["2fa_user_id"] = user.id
                session["2fa_next"] = request.args.get("next", "")
                # Log 2FA redirect
                _log_audit(user, "login_2fa_required", "login", "pending", ip_address, user_agent, {"email": email})
                return redirect(url_for("auth.verify_2fa"))
            login_user(user)
            # Log successful login
            _log_audit(user, "login_success", "login", "success", ip_address, user_agent, {"email": email})
            next_page = request.args.get("next")
            return redirect(next_page or url_for("dashboard.index"))

        # Log failed login attempt
        _log_audit(user, "login_failed", "login", "failed", ip_address, user_agent, {"email": email})
        flash_i18n("flash.invalid_credentials", "error")
    return render_template("auth/login.html")


@auth_bp.route("/logout")
@login_required
def logout():
    # Log logout
    ip_address = request.headers.get("X-Forwarded-For", request.remote_addr)
    user_agent = request.headers.get("User-Agent", "")[:500]
    _log_audit(current_user, "logout", "login", "success", ip_address, user_agent)
    logout_user()
    return redirect(url_for("auth.login"))


@auth_bp.route("/verify-email/<token>")
def verify_email(token):
    user = User.verify_token(token, "email-verify", expires_sec=86400)
    if not user:
        flash("Invalid or expired verification link.", "error")
        return redirect(url_for("auth.login"))
    if not user.email_verified:
        user.email_verified = True
        user.email_verified_at = datetime.utcnow()
        db.session.commit()
    flash("Email verified successfully!", "success")
    if current_user.is_authenticated:
        return redirect(url_for("dashboard.index"))
    return redirect(url_for("auth.login"))


@auth_bp.route("/resend-verification")
@login_required
@limiter.limit("3 per hour")
def resend_verification():
    if current_user.email_verified:
        flash("Email already verified.", "info")
        return redirect(url_for("dashboard.index"))
    _send_verification_email(current_user)
    flash("Verification email sent!", "success")
    return redirect(url_for("dashboard.index"))


@auth_bp.route("/forgot-password", methods=["GET", "POST"])
@limiter.limit("5 per hour")
def forgot_password():
    if request.method == "POST":
        email = request.form.get("email", "").strip().lower()
        user = User.query.filter_by(email=email).first()
        if user:
            _send_reset_email(user)
        flash("If an account exists with that email, a reset link has been sent.", "success")
        return redirect(url_for("auth.login"))
    return render_template("auth/forgot_password.html")


@auth_bp.route("/reset-password/<token>", methods=["GET", "POST"])
@limiter.limit("10 per hour")
def reset_password(token):
    user = User.verify_token(token, "password-reset", expires_sec=3600)
    if not user:
        flash("Invalid or expired reset link.", "error")
        return redirect(url_for("auth.forgot_password"))
    if request.method == "POST":
        password = request.form.get("password", "")
        confirm = request.form.get("confirm_password", "")
        if len(password) < 8:
            flash("Password must be at least 8 characters.", "error")
            return render_template("auth/reset_password.html", token=token)
        if password != confirm:
            flash("Passwords do not match.", "error")
            return render_template("auth/reset_password.html", token=token)
        user.set_password(password)
        db.session.commit()
        flash("Password reset successfully! Please log in.", "success")
        return redirect(url_for("auth.login"))
    return render_template("auth/reset_password.html", token=token)


@auth_bp.route("/profile", methods=["GET", "POST"])
@login_required
def profile():
    if request.method == "POST":
        action = request.form.get("action")
        if action == "update_profile":
            name = request.form.get("name", "").strip()
            language = request.form.get("language", "ar")
            currency = request.form.get("currency", "SAR")
            if name:
                current_user.name = name
            current_user.language_pref = language
            current_user.currency = currency
            db.session.commit()
            flash_i18n("flash.profile_updated", "success")
        elif action == "change_password":
            current_pw = request.form.get("current_password", "")
            new_pw = request.form.get("new_password", "")
            confirm = request.form.get("confirm_password", "")
            if not current_user.check_password(current_pw):
                flash_i18n("flash.wrong_password", "error")
            elif len(new_pw) < 8:
                flash_i18n("flash.password_too_short", "error")
            elif new_pw != confirm:
                flash_i18n("flash.password_mismatch", "error")
            else:
                current_user.set_password(new_pw)
                db.session.commit()
                flash_i18n("flash.password_changed", "success")
        return redirect(url_for("auth.profile"))

    from app.models.platform_keys import UserPlatformKey, PLATFORM_REGISTRY
    from app.models.organization import SponsorProfile, Organization
    user_keys = {pk.platform: pk for pk in UserPlatformKey.query.filter_by(user_id=current_user.id).all()}
    is_admin = getattr(current_user, 'is_admin', False)
    visible_platforms = {
        k: v for k, v in PLATFORM_REGISTRY.items()
        if not v.get("admin_only") or is_admin
    }
    sponsor_request = SponsorProfile.query.filter_by(user_id=current_user.id).first()
    return render_template("auth/profile.html",
        platform_registry=visible_platforms,
        user_keys=user_keys,
        sponsor_request=sponsor_request,
    )


@auth_bp.route("/profile/platform-key", methods=["POST"])
@login_required
def save_platform_key():
    """Save or update a platform API key."""
    from app.models.platform_keys import UserPlatformKey, PLATFORM_REGISTRY
    platform = request.form.get("platform", "").strip()
    if platform not in PLATFORM_REGISTRY:
        flash("منصة غير معروفة.", "error")
        return redirect(url_for("auth.profile"))

    pk = UserPlatformKey.query.filter_by(user_id=current_user.id, platform=platform).first()
    if not pk:
        pk = UserPlatformKey(user_id=current_user.id, platform=platform)
        db.session.add(pk)

    info = PLATFORM_REGISTRY[platform]
    for field in info["fields"]:
        val = request.form.get(field, "").strip()
        if val:
            setattr(pk, field, val)

    pk.is_active = True
    db.session.commit()
    flash(f"تم حفظ مفتاح {info['name_ar']} بنجاح.", "success")
    return redirect(url_for("auth.profile") + "#platforms")


@auth_bp.route("/profile/platform-key/delete", methods=["POST"])
@login_required
def delete_platform_key():
    """Delete a platform API key."""
    from app.models.platform_keys import UserPlatformKey, PLATFORM_REGISTRY
    platform = request.form.get("platform", "").strip()
    pk = UserPlatformKey.query.filter_by(user_id=current_user.id, platform=platform).first()
    if pk:
        db.session.delete(pk)
        db.session.commit()
        info = PLATFORM_REGISTRY.get(platform, {})
        flash(f"تم حذف مفتاح {info.get('name_ar', platform)}.", "success")
    return redirect(url_for("auth.profile") + "#platforms")


def _send_verification_email(user):
    from flask import current_app
    from flask_mail import Message
    try:
        token = user.generate_token("email-verify")
        verify_url = url_for("auth.verify_email", token=token, _external=True)
        msg = Message(
            "Verify Your Email - Jadwa AI",
            recipients=[user.email],
        )
        msg.html = f"""
        <div style="font-family:Arial,sans-serif;max-width:500px;margin:0 auto;padding:20px">
            <h2 style="color:#D2AF20">Jadwa AI</h2>
            <p>Hello {user.name},</p>
            <p>Please verify your email by clicking the button below:</p>
            <a href="{verify_url}" style="display:inline-block;background:#D2AF20;color:#000;padding:12px 24px;border-radius:8px;text-decoration:none;font-weight:bold">Verify Email</a>
            <p style="color:#999;font-size:12px;margin-top:20px">This link expires in 24 hours.</p>
        </div>
        """
        mail.send(msg)
    except Exception as e:
        current_app.logger.warning(f"Could not send verification email: {e}")


def _send_reset_email(user):
    from flask import current_app
    from flask_mail import Message
    try:
        token = user.generate_token("password-reset")
        reset_url = url_for("auth.reset_password", token=token, _external=True)
        msg = Message(
            "Reset Your Password - Jadwa AI",
            recipients=[user.email],
        )
        msg.html = f"""
        <div style="font-family:Arial,sans-serif;max-width:500px;margin:0 auto;padding:20px">
            <h2 style="color:#D2AF20">Jadwa AI</h2>
            <p>Hello {user.name},</p>
            <p>You requested a password reset. Click the button below:</p>
            <a href="{reset_url}" style="display:inline-block;background:#D2AF20;color:#000;padding:12px 24px;border-radius:8px;text-decoration:none;font-weight:bold">Reset Password</a>
            <p style="color:#999;font-size:12px;margin-top:20px">This link expires in 1 hour. If you didn't request this, ignore this email.</p>
        </div>
        """
        mail.send(msg)
    except Exception as e:
        current_app.logger.warning(f"Could not send reset email: {e}")


@auth_bp.route("/setup-2fa", methods=["GET", "POST"])
@login_required
def setup_2fa():
    import pyotp
    import qrcode
    import io
    import base64

    if request.method == "POST":
        code = request.form.get("code", "").strip()
        secret = current_user.totp_secret
        if not secret:
            flash("Setup error. Try again.", "error")
            return redirect(url_for("auth.setup_2fa"))
        totp = pyotp.TOTP(secret)
        if totp.verify(code, valid_window=1):
            current_user.two_factor_enabled = True
            db.session.commit()
            flash("2FA enabled successfully!", "success")
            return redirect(url_for("auth.profile"))
        flash("Invalid code. Try again.", "error")
        return redirect(url_for("auth.setup_2fa"))

    if not current_user.totp_secret:
        current_user.totp_secret = pyotp.random_base32()
        db.session.commit()

    totp = pyotp.TOTP(current_user.totp_secret)
    uri = totp.provisioning_uri(name=current_user.email, issuer_name="Jadwa AI")

    img = qrcode.make(uri)
    buf = io.BytesIO()
    img.save(buf, format="PNG")
    buf.seek(0)
    qr_b64 = base64.b64encode(buf.read()).decode()

    return render_template("auth/setup_2fa.html", qr_b64=qr_b64, secret=current_user.totp_secret)


@auth_bp.route("/disable-2fa", methods=["POST"])
@login_required
def disable_2fa():
    code = request.form.get("code", "").strip()
    if current_user.totp_secret:
        import pyotp
        totp = pyotp.TOTP(current_user.totp_secret)
        if totp.verify(code, valid_window=1):
            current_user.two_factor_enabled = False
            current_user.totp_secret = None
            db.session.commit()
            flash("2FA disabled.", "success")
        else:
            flash("Invalid code.", "error")
    return redirect(url_for("auth.profile"))


@auth_bp.route("/verify-2fa", methods=["GET", "POST"])
@limiter.limit("10 per hour")
def verify_2fa():
    from flask import session
    user_id = session.get("2fa_user_id")
    if not user_id:
        return redirect(url_for("auth.login"))

    if request.method == "POST":
        code = request.form.get("code", "").strip()
        user = User.query.get(user_id)
        if user and user.totp_secret:
            import pyotp
            totp = pyotp.TOTP(user.totp_secret)
            if totp.verify(code, valid_window=1):
                session.pop("2fa_user_id", None)
                next_page = session.pop("2fa_next", "")
                # Log successful 2FA login
                ip_address = request.headers.get("X-Forwarded-For", request.remote_addr)
                user_agent = request.headers.get("User-Agent", "")[:500]
                _log_audit(user, "login_2fa_success", "login", "success", ip_address, user_agent)
                login_user(user)
                return redirect(next_page or url_for("dashboard.index"))
        # Log failed 2FA attempt
        ip_address = request.headers.get("X-Forwarded-For", request.remote_addr)
        user_agent = request.headers.get("User-Agent", "")[:500]
        _log_audit(user, "login_2fa_failed", "login", "failed", ip_address, user_agent)
        flash("Invalid 2FA code.", "error")

    return render_template("auth/verify_2fa.html")


def _log_audit(user, action, log_type, status, ip_address, user_agent, details=None):
    """Helper function to log audit events."""
    from app.models.features import AuditLog
    log_data = {"email": user.email if user else "unknown"}
    if details:
        log_data.update(details)

    # Get IP geolocation
    country, city = _get_ip_location(ip_address)

    log = AuditLog(
        user_id=user.id if user else None,
        action=action,
        log_type=log_type,
        status=status,
        resource_type="User",
        resource_id=user.id if user else None,
        ip_address=ip_address,
        user_agent=user_agent,
        country=country,
        city=city,
        details=log_data
    )
    db.session.add(log)
    db.session.commit()


def _get_ip_location(ip_address):
    """Get country and city from IP address using free IP-API."""
    import requests

    if not ip_address or ip_address in ["127.0.0.1", "localhost", "::1"]:
        return None, None

    try:
        # Using free ip-api.com (no API key required for basic usage)
        response = requests.get(f"http://ip-api.com/json/{ip_address}", timeout=1)
        if response.status_code == 200:
            data = response.json()
            if data.get("status") == "success":
                return data.get("country"), data.get("city")
    except Exception:
        pass

    return None, None


@auth_bp.route("/sponsor-request", methods=["POST"])
@login_required
def submit_sponsor_request():
    """Submit a sponsorship request from user profile."""
    from app.models.organization import SponsorProfile, Organization
    from app.utils.uploads import upload_logo

    # Check if user already has a sponsor request
    existing = SponsorProfile.query.filter_by(user_id=current_user.id).first()
    if existing:
        flash("لديك بالفعل طلب رعاية قيد المراجعة.", "info")
        return redirect(url_for("auth.profile"))

    logo_url = request.form.get("logo_url", "").strip() or None
    tier = request.form.get("tier", "bronze")
    notes = request.form.get("notes", "").strip() or None
    use_organization = request.form.get("use_organization") == "1"

    if use_organization and current_user.organization:
        org = current_user.organization
    else:
        flash("يجب أن تكون مرتبطاً بمنظمة لتقديم طلب الرعاية.", "error")
        return redirect(url_for("auth.profile"))

    # Handle logo upload
    if 'logo' in request.files:
        logo = request.files['logo']
        if logo and logo.filename:
            uploaded_url = upload_logo(logo)
            if uploaded_url:
                logo_url = uploaded_url

    # Check if organization already has a sponsor profile
    existing_org_sponsor = SponsorProfile.query.filter_by(organization_id=org.id).first()
    if existing_org_sponsor:
        flash("هذه المنظمة لديها بالفعل ملف راعي. يرجى التواصل مع الإدارة.", "error")
        return redirect(url_for("auth.profile"))

    # Create sponsor profile
    sponsor = SponsorProfile(
        organization_id=org.id,
        user_id=current_user.id,
        logo_url=logo_url,
        tier=tier,
        status="pending",
        notes=notes
    )

    db.session.add(sponsor)
    db.session.commit()

    flash("تم إرسال طلب الرعاية! سيتم مراجعته من قبل الإدارة.", "success")
    return redirect(url_for("auth.profile"))


# ═══════════════════════════════════════════════════════════════════════════════
#  Google OAuth Routes
# ═════════════════════════════════════════════════════════════════════════════════════════════════

@auth_bp.route("/google/login")
@limiter.limit("10 per hour")
def google_login():
    """Redirect to Google OAuth login."""
    from flask import session
    from app.auth.google_oauth import GoogleOAuth
    from flask import current_app

    # Check if already logged in
    if current_user.is_authenticated:
        current_app.logger.info(f"User {current_user.email} already authenticated, redirecting to dashboard")
        flash("أنت مسجل بالفعل", "info")
        return redirect(url_for('dashboard.index'))

    # Check if registration is enabled (for new users)
    from app.models.features import SystemSetting
    if not SystemSetting.get("registration_enabled", default=True):
        return render_template("auth/registration_disabled.html")

    # Store the intended redirect after login
    next_url = request.args.get('next') or url_for('dashboard.index')
    session['oauth_next'] = next_url

    # Check for OAuth error in URL
    if 'error' in request.args:
        error = request.args.get('error')
        current_app.logger.error(f"Google OAuth error from URL: {error}")
        flash(f"Google OAuth error: {error}", "error")
        # Don't redirect to avoid loop - show error on login page
        return redirect(url_for('auth.login'))

    oauth = GoogleOAuth()
    return redirect(oauth.get_authorization_url())


@auth_bp.route("/google/callback")
@limiter.limit("20 per hour")
def google_callback():
    """Handle Google OAuth callback."""
    from flask import session, current_app, request as req
    from app.auth.google_oauth import GoogleOAuth

    oauth = GoogleOAuth()

    # Log the request for debugging
    current_app.logger.info(f"Google callback received: {req.url}")
    current_app.logger.info(f"Request method: {req.method}")
    current_app.logger.info(f"Request args: {dict(req.args)}")

    # Handle OAuth error
    if 'error' in req.args:
        error = req.args.get('error')
        error_description = req.args.get('error_description', '')
        current_app.logger.error(f"Google OAuth error: {error} - {error_description}")
        flash(f"حدث خطأ أثناء تسجيل الدخول عبر Google: {error}", "error")
        return redirect(url_for('auth.login'))

    # Check if we have an authorization code
    code = req.args.get('code')
    if not code:
        current_app.logger.error("No authorization code in callback")
        flash("حدث خطأ في التحقق من Google - لا يوجد رمز تفويض", "error")
        return redirect(url_for('auth.login'))

    # Exchange authorization code for tokens
    try:
        current_app.logger.info("Attempting to fetch token...")
        current_app.logger.info(f"Callback URL: {req.url}")
        current_app.logger.info(f"OAuth redirect_uri: {oauth.redirect_uri}")
        credentials = oauth.fetch_token(req.url)
        current_app.logger.info(f"Token fetched successfully")

        if 'token' not in credentials:
            current_app.logger.error(f"No token in credentials: {list(credentials.keys())}")
            flash("حدث خطأ في التحقق من Google - لم يتم الحصول على رمز", "error")
            return redirect(url_for('auth.login'))

        user_info = oauth.get_user_info(credentials)
        current_app.logger.info(f"User info retrieved: {user_info.get('email', 'no-email')}")
    except ValueError as e:
        error_msg = str(e)
        current_app.logger.error(f"Google OAuth ValueError: {error_msg}")
        import traceback
        current_app.logger.error(traceback.format_exc())
        # Show detailed error to user
        if "redirect_uri_mismatch" in error_msg.lower() or "redirect" in error_msg.lower():
            flash(f"خطأ في إعدادات Google: redirect_uri غير مطابقة. الرابط المطلوب: https://jadwaai.com/auth/google/callback", "error")
        else:
            flash(f"حدث خطأ في التحقق من Google: {error_msg}", "error")
        return redirect(url_for('auth.login'))
    except Exception as e:
        error_msg = str(e)
        current_app.logger.error(f"Google OAuth error: {error_msg}")
        import traceback
        current_app.logger.error(traceback.format_exc())
        flash(f"حدث خطأ في التحقق من Google: {error_msg}", "error")
        return redirect(url_for('auth.login'))

    # Check if user already exists with this Google ID
    from app.models.user import User

    # First check for active users with this Google ID
    user = User.query.filter_by(google_id=user_info['google_id'], deleted_at=None).first()

    # If not found by google_id, check for deleted users with same email
    if not user:
        deleted_user = User.query.filter(
            User.email.like(f"%{user_info['email']}%"),
            User.deleted_at.isnot(None)
        ).first()

        if deleted_user:
            # Permanently delete the old deleted user to allow re-registration
            current_app.logger.info(f"Found deleted user with same Google email, permanently deleting: {deleted_user.id}")
            # Delete all related data for this user
            from app.models.report import Report
            from app.models.campaign import Campaign
            from app.models.society import SocietyPost

            # Delete user's reports
            Report.query.filter_by(user_id=deleted_user.id).delete()
            # Delete user's campaigns
            Campaign.query.filter_by(user_id=deleted_user.id).delete()
            # Delete user's society posts
            SocietyPost.query.filter_by(user_id=deleted_user.id).delete()

            db.session.delete(deleted_user)
            db.session.commit()
            user = None

    # Also check by email directly (in case user exists but google_id was cleared)
    if not user:
        user = User.query.filter_by(email=user_info['email'], deleted_at=None).first()

    if user:
        # Existing user - update tokens and log in
        # If user was soft-deleted, restore them
        if user.deleted_at:
            user.deleted_at = None
            user.deleted_by_id = None
            user.is_active = True

        user.google_access_token = credentials['token']
        user.google_refresh_token = credentials['refresh_token']
        user.google_id = user_info['google_id']  # Restore google_id
        user.google_email = user_info['email']
        user.auth_provider = 'both'
        if not user.email_verified:
            user.email_verified = user_info['verified_email']
            user.email_verified_at = datetime.utcnow()
        db.session.commit()

        # Ensure session is permanent and persists
        session.permanent = True
        login_user(user)
        flash(f"مرحباً {user.name}، لقد سجلت الدخول بنجاح", "success")

        # Redirect to next URL or dashboard
        next_url = session.pop('oauth_next', url_for('dashboard.index'))
        return redirect(next_url)
    else:
        # New user - check if registration is enabled
        from app.models.features import SystemSetting
        if not SystemSetting.get("registration_enabled", default=True):
            return render_template("auth/registration_disabled.html")

        # Redirect to registration completion with data collection
        session['google_credentials'] = credentials
        session['google_user_info'] = user_info
        session['auth_provider'] = 'google'
        return redirect(url_for('auth.google_register_form'))


@auth_bp.route("/register-with-google")
@limiter.limit("5 per hour")
def register_with_google():
    """Display registration form with Google OAuth option."""
    return render_template('auth/register_with_google.html')


@auth_bp.route("/test-google-oauth-config")
@limiter.limit("20 per hour")
def test_google_oauth_config():
    """Test endpoint to verify Google OAuth configuration."""
    from flask import current_app, jsonify
    import os

    config = {
        "client_id_exists": bool(os.getenv("GOOGLE_CLIENT_ID")),
        "client_secret_exists": bool(os.getenv("GOOGLE_CLIENT_SECRET")),
        "redirect_uri": os.getenv("GOOGLE_REDIRECT_URI", "Not set"),
        "client_id_preview": os.getenv("GOOGLE_CLIENT_ID", "")[:20] + "..." if os.getenv("GOOGLE_CLIENT_ID") else None,
    }

    return jsonify(config)


@auth_bp.route("/test-google-token")
@limiter.limit("5 per hour")
def test_google_token():
    """Test endpoint to verify Google OAuth token exchange."""
    from flask import request, session, current_app, jsonify
    from app.auth.google_oauth import GoogleOAuth
    from urllib.parse import urlparse, parse_qs

    code = request.args.get('code')
    if not code:
        return jsonify({
            "error": "No code provided",
            "message": "Please provide a code parameter"
        }), 400

    try:
        oauth = GoogleOAuth()
        redirect_uri = oauth.redirect_uri

        # Simulate token exchange
        import requests
        token_url = "https://oauth2.googleapis.com/token"
        data = {
            'code': code,
            'client_id': oauth.client_id,
            'client_secret': oauth.client_secret,
            'redirect_uri': redirect_uri,
            'grant_type': 'authorization_code'
        }

        current_app.logger.info(f"Test token exchange: code={code[:20]}...")
        response = requests.post(token_url, data=data)

        current_app.logger.info(f"Token response status: {response.status_code}")
        current_app.logger.info(f"Token response: {response.text[:200]}")

        if response.status_code == 200:
            token_data = response.json()
            return jsonify({
                "success": True,
                "token_data": token_data
            })
        else:
            return jsonify({
                "success": False,
                "error": f"Token request failed: {response.status_code}",
                "response": response.text[:500]
            }), 400

    except Exception as e:
        current_app.logger.error(f"Test token exchange error: {e}")
        import traceback
        current_app.logger.error(traceback.format_exc())
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@auth_bp.route("/test-google-auth")
@limiter.limit("5 per hour")
def test_google_auth():
    """Test Google OAuth without state validation."""
    from flask import session, current_app
    from app.auth.google_oauth import GoogleOAuth

    oauth = GoogleOAuth()
    auth_url = oauth.get_authorization_url()
    current_app.logger.info(f"Test Google Auth URL: {auth_url[:100]}...")

    # Store the URL in session for testing
    session['test_google_auth_url'] = auth_url

    return redirect(auth_url)


@auth_bp.route("/oauth-debug")
@limiter.limit("20 per hour")
def oauth_debug():
    """Debug page for Google OAuth."""
    return render_template('auth/oauth_debug.html')


@auth_bp.route("/debug-google-callback")
@limiter.limit("5 per hour")
def debug_google_callback():
    """Debug endpoint to test Google callback."""
    from flask import request, current_app, session
    from app.auth.google_oauth import GoogleOAuth

    current_app.logger.info(f"Debug callback received: {request.url}")
    current_app.logger.info(f"Request args: {dict(request.args)}")
    current_app.logger.info(f"Session keys: {list(session.keys())}")

    return f"Debug: URL={request.url}, Args={dict(request.args)}, Session={list(session.keys())}"


@auth_bp.route("/google-register-form")
@limiter.limit("5 per hour")
def google_register_form():
    """Display registration form after Google OAuth for new users."""
    from flask import session, current_app

    google_credentials = session.get('google_credentials')
    google_user_info = session.get('google_user_info')

    if not google_credentials or not google_user_info:
        flash("انتهتت جلسة Google. يرجى المحاولة مرة أخرى.", "error")
        return redirect(url_for('auth.login'))

    return render_template('auth/register_with_google.html',
                         google_email=google_user_info.get('email'),
                         google_name=google_user_info.get('name', ''))


@auth_bp.route("/google-register-submit", methods=["POST"])
@limiter.limit("10 per hour")
def google_register_submit():
    """Process Google registration with user data."""
    from flask import session, current_app

    google_credentials = session.get('google_credentials')
    google_user_info = session.get('google_user_info')

    if not google_credentials or not google_user_info:
        flash("انتهتت جلسة Google. يرجى المحاولة مرة أخرى.", "error")
        return redirect(url_for('auth.login'))

    if request.method == "POST":
        # Get form data
        name = request.form.get("name", "").strip()
        account_type = request.form.get("account_type", "entrepreneur")
        company_name = request.form.get("company_name", "").strip() or None
        organization_id = request.form.get("organization_id")
        interests = request.form.getlist("interests")

        # Validate
        if not name:
            flash("الاسم الكامل مطلوب", "error")
            return render_template('auth/register_with_google.html',
                                 google_email=google_user_info.get('email'),
                                 google_name=name)

        # Create user with Google credentials
        from app.models.user import User

        # Check if email already exists
        existing = User.query.filter_by(email=google_user_info['email']).first()
        if existing:
            flash("هذا البريد الإلكتروني مسجل بالفعل", "error")
            return redirect(url_for('auth.login'))

        user = User(
            name=name,
            full_name=name,
            email=google_user_info['email'],
            google_id=google_user_info['google_id'],
            google_email=google_user_info['email'],
            google_access_token=google_credentials['token'],
            google_refresh_token=google_credentials['refresh_token'],
            auth_provider='google',
            email_verified=True,
            email_verified_at=datetime.utcnow(),
            account_type=account_type,
            company_name=company_name,
            interests_json=interests if interests else None
        )

        # Handle organization selection
        if organization_id:
            try:
                user.organization_id = int(organization_id)
            except (ValueError, TypeError):
                pass

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

        # Auto-create FactoryPartner record for factory accounts
        if account_type == "factory" and company_name:
            from app.models.services import FactoryPartner
            fp = FactoryPartner(
                name=company_name, name_ar=company_name,
                user_id=user.id, sectors_json=interests,
                is_verified=False, is_active=True,
            )
            db.session.add(fp)
            user.factory_partner_id = fp.id
            db.session.commit()

        # Clear all session data
        for key in list(session.keys()):
            if key.startswith('google_') or key == 'pending_google_token' or key == 'pending_google_refresh':
                session.pop(key, None)

        # Ensure session is permanent and persists
        session.permanent = True
        login_user(user)
        flash("تم إنشاء حسابك بنجاح!", "success")
        return redirect(url_for('dashboard.index'))

    return render_template('auth/register_with_google.html',
                         google_email=google_user_info.get('email'),
                         google_name=google_user_info.get('name', ''))


@auth_bp.route("/register-google-submit", methods=["POST"])
@limiter.limit("10 per hour")
def register_google_complete_submit():
    """Complete Google registration with password and details."""
    from flask import session, current_app

    google_email = session.get('reg_google_email')
    google_name = session.get('reg_google_name', '')
    google_id = session.get('reg_google_id')
    picture = session.get('reg_google_picture')

    if not google_email or not google_id:
        flash("انتهتت جلسة Google. يرجى المحاولة مرة أخرى.", "error")
        return redirect(url_for('auth.login'))

    if request.method == "POST":
        password = request.form.get("password", "")
        confirm_password = request.form.get("confirm_password", "")
        name = request.form.get("name", "").strip() or google_name
        language = request.form.get("language", "ar")
        currency = request.form.get("currency", "SAR")
        account_type = request.form.get("account_type", "entrepreneur")

        if not password or len(password) < 8:
            flash("يجب إدخال كلمة مرور لا تقل عن 8 أحرف", "error")
            return render_template('auth/register_google.html',
                                 google_email=google_email,
                                 google_name=google_name)

        if password != confirm_password:
            flash("كلمتا المرور غير متطابقة", "error")
            return render_template('auth/register_google.html',
                                 google_email=google_email,
                                 google_name=google_name)

        # Create user with Google credentials
        from app.models.user import User

        # Check if email already exists
        existing = User.query.filter_by(email=google_email).first()
        if existing:
            flash("هذا البريد الإلكتروني مسجل بالفعل", "error")
            return redirect(url_for('auth.login'))

        user = User(
            name=name,
            email=google_email,
            google_id=google_id,
            google_email=google_email,
            google_access_token=session.pop('pending_google_token', None),
            google_refresh_token=session.pop('pending_google_refresh', None),
            auth_provider='google',
            email_verified=True,
            email_verified_at=datetime.utcnow(),
            language_pref=language,
            currency=currency,
            account_type=account_type,
            avatar_url=picture
        )
        user.set_password(password)
        db.session.add(user)
        db.session.commit()

        # Clear all session data
        for key in list(session.keys()):
            if key.startswith('reg_') or key == 'pending_google_token' or key == 'pending_google_refresh':
                session.pop(key, None)

        login_user(user)
        flash("تم إنشاء حسابك بنجاح!", "success")
        return redirect(url_for('dashboard.index'))

    return render_template('auth/register_google.html',
                         google_email=google_email,
                         google_name=google_name)


# ═══════════════════════════════════════════════════════════════════════════════
#  Multi-step Registration with Email Selection & OTP
# ═════════════════════════════════════════════════════════════════════════════════════════════════

@auth_bp.route("/register/step1", methods=["GET", "POST"])
@limiter.limit("10 per hour")
def register_step1():
    """Step 1: Basic info (name, password)."""
    if current_user.is_authenticated:
        return redirect(url_for("dashboard.index"))

    # Clear any previous registration session data
    from flask import session
    for key in list(session.keys()):
        if key.startswith('reg_'):
            session.pop(key, None)

    if request.method == "POST":
        name = request.form.get("name", "").strip()
        password = request.form.get("password", "")
        confirm_password = request.form.get("confirm_password", "")

        if not name or not password:
            flash("جميع الحقول مطلوبة", "error")
            return render_template("auth/register_step1.html")

        if len(password) < 8:
            flash("كلمة المرور يجب أن تكون 8 أحرف على الأقل", "error")
            return render_template("auth/register_step1.html")

        if password != confirm_password:
            flash("كلمتا المرور غير متطابقة", "error")
            return render_template("auth/register_step1.html")

        # Store in session
        session['reg_name'] = name
        session['reg_password'] = password
        session['reg_step1_complete'] = True

        return redirect(url_for('auth.register_step2'))

    return render_template("auth/register_step1.html")


@auth_bp.route("/register/step2", methods=["GET", "POST"])
@limiter.limit("10 per hour")
def register_step2():
    """Step 2: Email selection (Gmail or Personal) + send OTP."""
    from flask import session

    # Check if step 1 is complete
    if not session.get('reg_step1_complete'):
        flash("يرجى البدء من الخطوة الأولى", "error")
        return redirect(url_for('auth.register_step1'))

    if request.method == "POST":
        email_type = request.form.get("email_type", "personal")
        email = request.form.get("email", "").strip().lower()

        if not email_type or not email:
            flash("جميع الحقول مطلوبة", "error")
            return render_template("auth/register_step2.html")

        if email_type == "gmail" and not email.endswith("@gmail.com"):
            flash("يرجى إدخال بريد Gmail صحيح", "error")
            return render_template("auth/register_step2.html",
                                 email_type=email_type,
                                 email=email)

        # Check if email already exists
        from app.models.user import User
        if User.query.filter_by(email=email).first():
            flash("هذا البريد الإلكتروني مسجل بالفعل", "error")
            return render_template("auth/register_step2.html",
                                 email_type=email_type,
                                 email=email)

        # Generate and send OTP
        from app.auth.otp_service import generate_otp, generate_expires_at, send_otp_email_en
        otp = generate_otp()
        expires_at = generate_expires_at()

        # Store in session
        session['reg_email_type'] = email_type
        session['reg_email'] = email
        session['reg_otp'] = {
            'code': otp,
            'expires_at': expires_at.isoformat()
        }

        # Send OTP email
        name = session.get('reg_name', 'User')
        if send_otp_email_en(email, otp, name):
            flash(f"تم إرسال رمز التحقق إلى {email}", "success")
            return redirect(url_for('auth.register_step3'))
        else:
            flash("فشل إرسال رمز التحقق. يرجى المحاولة لاحقاً", "error")
            return render_template("auth/register_step2.html",
                                 email_type=email_type,
                                 email=email)

    return render_template("auth/register_step2.html",
                         email_type=request.args.get('email_type', session.get('reg_email_type', 'personal')),
                         email=request.args.get('email', session.get('reg_email', '')))


@auth_bp.route("/register/step3", methods=["GET", "POST"])
@limiter.limit("20 per hour")
def register_step3():
    """Step 3: Verify OTP and proceed."""
    from flask import session
    from app.auth.otp_service import verify_otp_from_session, clear_otp

    # Check if previous steps are complete
    if not session.get('reg_step1_complete') or not session.get('reg_otp'):
        flash("يرجى إكمال الخطوات السابقة أولاً", "error")
        return redirect(url_for('auth.register_step1'))

    email_type = session.get('reg_email_type', 'personal')
    email = session.get('reg_email', '')

    if request.method == "POST":
        otp = request.form.get("otp", "").strip()

        if not otp:
            flash("يرجى إدخال رمز التحقق", "error")
            return render_template("auth/register_step3.html",
                                 email_type=email_type,
                                 email=email)

        # Verify OTP
        if verify_otp_from_session(session['reg_otp'], otp):
            # OTP is valid - proceed
            session['reg_otp_verified'] = True

            if email_type == 'gmail':
                # For Gmail, redirect to Google OAuth
                return redirect(url_for('auth.register_step4'))
            else:
                # For personal email, proceed to registration completion
                return redirect(url_for('auth.register_complete'))
        else:
            flash("رمز التحقق غير صحيح أو منتهي الصلاحية", "error")
            return render_template("auth/register_step3.html",
                                 email_type=email_type,
                                 email=email)

    return render_template("auth/register_step3.html",
                         email_type=email_type,
                         email=email)


@auth_bp.route("/register/step4", methods=["GET", "POST"])
@limiter.limit("20 per hour")
def register_step4():
    """Step 4: Google OAuth connection (for Gmail users)."""
    from flask import session

    # Check if previous steps are complete
    if not session.get('reg_otp_verified') or session.get('reg_email_type') != 'gmail':
        flash("يرجى اختيار Gmail والتحقق من بريدك أولاً", "error")
        return redirect(url_for('auth.register_step2'))

    if session.get('reg_google_connected'):
        # Already connected to Google
        return redirect(url_for('auth.register_complete'))

    return render_template("auth/register_step4.html",
                         google_email=session.get('reg_email', ''))


@auth_bp.route("/register-complete", methods=["GET", "POST"])
@limiter.limit("10 per hour")
def register_complete():
    """Final registration step - create account."""
    from flask import session
    from app.auth.otp_service import verify_otp_from_session
    from app.models.user import User

    # Check if steps are complete
    if not session.get('reg_otp_verified'):
        flash("يرجى التحقق من بريدك أولاً", "error")
        return redirect(url_for('auth.register_step3'))

    if request.method == "POST":
        email_type = session.get('reg_email_type', 'personal')
        google_connected = session.get('reg_google_connected', False)

        # Get stored data
        name = session.get('reg_name', '')
        password = session.get('reg_password', '')
        email = session.get('reg_email', '')
        google_id = session.get('reg_google_id')
        google_email = session.get('reg_google_email')
        google_token = session.get('pending_google_token')
        google_refresh = session.get('pending_google_refresh')

        # For Gmail users, require Google OAuth connection
        if email_type == 'gmail' and not google_connected:
            flash("يرجى ربط حساب Gmail أولاً", "error")
            return redirect(url_for('auth.register_step4'))

        # Check if email already exists
        existing = User.query.filter_by(email=email).first()
        if existing:
            flash("هذا البريد الإلكتروني مسجل بالفعل", "error")
            return redirect(url_for('auth.login'))

        # Create user
        user = User(
            name=name,
            email=email,
            email_verified=True,
            email_verified_at=datetime.utcnow(),
            language_pref='ar',
            currency='SAR'
        )

        # Set password for personal email users
        if email_type == 'personal':
            user.set_password(password)

        # Store Google data if available
        if google_id and google_email:
            user.google_id = google_id
            user.google_email = google_email
            user.google_access_token = google_token
            user.google_refresh_token = google_refresh
            user.auth_provider = 'google'

        user.email_preference = email_type
        if email_type == 'personal':
            user.personal_email = email
        else:
            user.personal_email = session.get('personal_email', None)

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

        # Clear registration session data
        for key in list(session.keys()):
            if key.startswith('reg_'):
                session.pop(key, None)
        session.pop('pending_google_token', None)
        session.pop('pending_google_refresh', None)

        login_user(user)
        flash("تم إنشاء حسابك بنجاح!", "success")
        return redirect(url_for('dashboard.index'))

    return render_template("auth/register_complete.html",
                         email_type=session.get('reg_email_type', 'personal'),
                         email=session.get('reg_email', ''))


@auth_bp.route("/register/resend-otp", methods=["POST"])
@limiter.limit("5 per hour")
def resend_otp():
    """Resend OTP for registration."""
    from flask import session
    from app.auth.otp_service import generate_otp, generate_expires_at, send_otp_email_en

    email = session.get('reg_email')
    email_type = session.get('reg_email_type')

    if not email:
        return jsonify({"success": False, "message": "لم يتم تحديد بريد بعد"})

    # Rate limiting check (simple in-memory)
    last_resent = session.get('last_otp_resend')
    if last_resent:
        from datetime import datetime, timedelta
        if datetime.utcnow() - last_resent < timedelta(minutes=1):
            return jsonify({"success": False, "message": "يرجى الانتظار دقيقة قبل إعادة الإرسال"})

    # Generate new OTP
    otp = generate_otp()
    expires_at = generate_expires_at()

    # Update session
    session['reg_otp'] = {
        'code': otp,
        'expires_at': expires_at.isoformat()
    }
    session['last_otp_resend'] = datetime.utcnow()

    # Send OTP
    name = session.get('reg_name', 'User')
    if send_otp_email_en(email, otp, name):
        return jsonify({"success": True, "message": "تم إعادة إرسال رمز التحقق"})
    else:
        return jsonify({"success": False, "message": "فشل إرسال رمز التحقق"})


@auth_bp.route("/link-google-account")
@login_required
@limiter.limit("10 per hour")
def link_google_account():
    """Link Google account to existing user."""
    from app.auth.google_oauth import GoogleOAuth

    oauth = GoogleOAuth()
    # Store return URL after linking
    from flask import session
    session['linking_google'] = True
    session['oauth_next'] = url_for('auth.profile')

    return redirect(oauth.get_authorization_url())


@auth_bp.route("/google-callback-link")
@limiter.limit("20 per hour")
def google_callback_link():
    """Handle Google OAuth callback for account linking."""
    from flask import session, current_app
    from app.auth.google_oauth import GoogleOAuth

    if not session.get('linking_google'):
        return redirect(url_for('auth.profile'))

    oauth = GoogleOAuth()

    # Handle OAuth error
    if 'error' in request.args:
        flash("حدث خطأ أثناء ربط حساب Google", "error")
        return redirect(url_for('auth.profile'))

    try:
        credentials = oauth.fetch_token(request.url)
        user_info = oauth.get_user_info(credentials)

        # Check if this Google account is already linked to another user
        from app.models.user import User
        existing = User.query.filter_by(google_id=user_info['google_id']).first()
        if existing and existing.id != current_user.id:
            flash("هذا حساب Google مرتبط بحساب آخر", "error")
            return redirect(url_for('auth.profile'))

        # Link to current user
        current_user.google_id = user_info['google_id']
        current_user.google_email = user_info['email']
        current_user.google_access_token = credentials['token']
        current_user.google_refresh_token = credentials['refresh_token']
        current_user.auth_provider = 'both'
        current_user.email_verified = user_info['verified_email']
        current_user.email_verified_at = datetime.utcnow()
        db.session.commit()

        session.pop('linking_google', None)

        flash("تم ربط حساب Google بنجاح!", "success")
        next_url = session.pop('oauth_next', url_for('auth.profile'))
        return redirect(next_url)

    except Exception as e:
        current_app.logger.error(f"Google link error: {e}")
        flash("حدث خطأ أثناء ربط حساب Google", "error")
        return redirect(url_for('auth.profile'))


@auth_bp.route("/unlink-google-account", methods=["POST"])
@login_required
@limiter.limit("10 per hour")
def unlink_google_account():
    """Unlink Google account from current user."""
    from app.models.user import User

    current_user.google_id = None
    current_user.google_email = None
    current_user.google_access_token = None
    current_user.google_refresh_token = None

    # Update auth_provider
    if current_user.personal_email:
        current_user.auth_provider = 'email'
    else:
        current_user.auth_provider = None

    db.session.commit()

    # Clear NotebookLM session data
    current_user.google_nlm_session_path = None
    current_user.google_nlm_connected_at = None

    flash("تم إلغاء ربط حساب Google", "success")
    return redirect(url_for('auth.profile'))
