from flask import Blueprint, render_template, session, redirect, url_for, request, flash
from extensions import get_db_connection
import os
import requests
import secrets
import urllib.parse

social_bp = Blueprint('social_bp', __name__)

LINKEDIN_CLIENT_ID = os.getenv("LINKEDIN_CLIENT_ID")
LINKEDIN_CLIENT_SECRET = os.getenv("LINKEDIN_CLIENT_SECRET")
LINKEDIN_REDIRECT_URI = os.getenv("LINKEDIN_REDIRECT_URI", 'http://localhost:5500/linkedin/callback')
# LINKEDIN_REDIRECT_URI = os.getenv("LINKEDIN_REDIRECT_URI", 'https://mk0kv4zf-5500.inc1.devtunnels.ms/linkedin/callback')
# LINKEDIN_REDIRECT_URI = os.getenv("LINKEDIN_REDIRECT_URI", 'https://connect.learntrail.co.in/linkedin/callback')

# =========================================================
# MISSING ROUTE FIXED HERE
# =========================================================
@social_bp.route('/switch_platform/<platform>')
def switch_platform(platform):
    """
    Switches the active platform in the session.
    Required by base.html template.
    """
    if 'user_id' not in session: 
        return redirect(url_for('auth_bp.signin'))
    
    if platform in ['linkedin', 'instagram']:
        session['active_platform'] = platform
        # Optional: Add flash message
        # flash(f"Switched to {platform.capitalize()}", "info")
    
    # Redirect to the view posts page or wherever the user was
    return redirect(url_for('post_bp.view_posts'))


# =========================================================
# CONNECT HUB & OAUTH ROUTES
# =========================================================
@social_bp.route('/connect_hub')
def connect_hub():
    if 'user_id' not in session: return redirect(url_for('auth_bp.signin'))
    
    # Optional: Check if already connected logic could go here
    return render_template('connect_hub.html')

@social_bp.route('/linkedin/login')
def linkedin_login():
    if not LINKEDIN_CLIENT_ID:
        flash("LinkedIn Client ID missing", "danger")
        return redirect(url_for('social_bp.connect_hub'))

    state = secrets.token_urlsafe(16)
    session["linkedin_state"] = state
    scopes = "openid profile email w_member_social"
    
    auth_url = (
        "https://www.linkedin.com/oauth/v2/authorization"
        f"?response_type=code&client_id={LINKEDIN_CLIENT_ID}"
        f"&redirect_uri={urllib.parse.quote(LINKEDIN_REDIRECT_URI)}"
        f"&scope={scopes}&state={state}"
    )
    return redirect(auth_url)

@social_bp.route('/linkedin/callback')
def linkedin_callback():
    # 1. Capture the authorization code from LinkedIn
    code = request.args.get("code")
    if not code:
        flash("❌ Authorization denied by LinkedIn.", "danger")
        return redirect(url_for('social_bp.connect_hub'))

    user_id = session.get('user_id')
    if not user_id:
        flash("❌ Session expired. Please sign in again.", "danger")
        return redirect(url_for('auth_bp.signin'))

    # 2. Exchange authorization code for an Access Token
    token_url = "https://www.linkedin.com/oauth/v2/accessToken"
    data = {
        "grant_type": "authorization_code",
        "code": code,
        "redirect_uri": LINKEDIN_REDIRECT_URI,
        "client_id": LINKEDIN_CLIENT_ID,
        "client_secret": LINKEDIN_CLIENT_SECRET
    }

    try:
        # Request access token
        r = requests.post(token_url, data=data, timeout=10)
        r.raise_for_status()
        token_data = r.json()
        access_token = token_data.get("access_token")

        if not access_token:
            flash("❌ Failed to retrieve access token.", "danger")
            return redirect(url_for('social_bp.connect_hub'))

        # 3. Fetch Profile Info (including Email) via OpenID Connect
        headers = {"Authorization": f"Bearer {access_token}"}
        profile_res = requests.get("https://api.linkedin.com/v2/userinfo", headers=headers, timeout=10).json()
        
        # Extract critical data points
        platform_user_id = profile_res.get("sub")  # LinkedIn Unique URN
        platform_email = profile_res.get("email") # LinkedIn Verified Email
        pic_url = profile_res.get("picture")      # Profile Picture
        user_name = profile_res.get("name", "LinkedIn User")

        # 4. Save/Update Data in the Database
        conn = get_db_connection()
        cursor = conn.cursor()
        
        # First, double-check that the user still exists in our primary users table
        cursor.execute("SELECT id FROM users WHERE id = %s", (user_id,))
        if not cursor.fetchone():
            cursor.close()
            flash("❌ User account mismatch. Please register again.", "danger")
            return redirect(url_for('auth_bp.signup'))

        # UPSERT into social_connections
        # This inserts a new record or updates the token/email if the user reconnects
        sql = """
            INSERT INTO social_connections 
            (user_id, platform, platform_user_id, platform_email, access_token, profile_pic_url)
            VALUES (%s, 'linkedin', %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE 
            platform_email = VALUES(platform_email),
            access_token = VALUES(access_token),
            profile_pic_url = VALUES(profile_pic_url),
            platform_user_id = VALUES(platform_user_id)
        """
        cursor.execute(sql, (user_id, platform_user_id, platform_email, access_token, pic_url))
        conn.commit()
        cursor.close()
        conn.close()

        # 5. Maintain Comprehensive Session for the Dashboard
        session['linkedin_token'] = access_token
        session['linkedin_user_urn'] = platform_user_id
        session['linkedin_email'] = platform_email
        session['user_pic'] = pic_url
        session['active_platform'] = 'linkedin'
        
        # Force session to save changes
        session.modified = True 

        # Debug print to console (optional)
        print(f"\n--- LinkedIn Session Verified: {platform_email} ---")

        flash(f"✅ Success! LinkedIn account ({platform_email}) connected.", "success")
        return redirect(url_for('content_bp.clear_and_generate'))
        
    except requests.exceptions.RequestException as e:
        print(f"[API ERROR] LinkedIn Token Exchange: {e}")
        flash("❌ Communication error with LinkedIn. Please try again.", "danger")
    except Exception as e:
        print(f"[DB/SYSTEM ERROR] Callback Logic: {e}")
        flash("❌ An internal error occurred while saving your connection.", "danger")

    return redirect(url_for('social_bp.connect_hub'))