#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
OAuth Flask Application Example

Complete example of Identitas with GitHub OAuth enabled.
"""

import os
import sys
from flask import Flask
from Identitas.interface.flask.routes.login_flask import login_bp
from Identitas.interface.flask.routes.logout_flask import logout_bp
from Identitas.interface.flask.routes.register_flask import register_bp
from Identitas.interface.flask.routes.oauth_flask import oauth_bp
from Identitas.interface.flask.utils.auth_utils import require_session
from Identitas.provider.api.init import init
from Identitas.provider.api.auth import register
from Identitas.provider.api.oauth import (
    register_oauth_provider, enable_oauth_provider,
    get_user_oauth_accounts, list_enabled_oauth_providers
)
from Identitas.provider.api.rbac import get_user_permissions_summary

# ============================================================
# Flask Application Setup
# ============================================================

app = Flask(__name__)
os.environ["IDENTITAS_JWT"] = "true"
os.environ["IDENTITAS_SIGNUP_REQUIREMENTS"] = "min_length=12,upper=1,lower=1,digits=2,special=1"
os.environ["OAUTH_GITHUB_CLIENT_ID"] = "replaceme"
os.environ["OAUTH_GITHUB_CLIENT_SECRET"] = "replaceme"
os.environ["IDENTITAS_REDIRECT_URI_GITHUB"] = "yourserver.address/auth/oauth/callback/github"

# Enable debug mode only if explicitly set
debug_mode = os.getenv("DEBUG", "false").lower() == "true"
engine = init(os.path.dirname(os.path.abspath(sys.argv[0])) + "/data" + "/auth.db", debug=debug_mode)

app.config["IDENTITAS_ENGINE"] = engine
app.config["IDENTITAS_LANG"] = "en"

# ============================================================
# Register Blueprint
# ============================================================

# Authentication routes
app.register_blueprint(login_bp)
app.register_blueprint(logout_bp)
app.register_blueprint(register_bp)

# OAuth routes (NEW!)
app.register_blueprint(oauth_bp)

# ============================================================
# Configure OAuth Providers
# ============================================================

def setup_oauth_providers():
    """
    Configure OAuth providers from environment variables or defaults.
    
    Environment variables:
    - OAUTH_GITHUB_ENABLED: "true" or "false"
    - OAUTH_GITHUB_CLIENT_ID: GitHub Client ID
    - OAUTH_GITHUB_CLIENT_SECRET: GitHub Client Secret
    """
    
    # GitHub OAuth
    if os.getenv("OAUTH_GITHUB_ENABLED", "true").lower() == "true":
        github_id = os.getenv("OAUTH_GITHUB_CLIENT_ID")
        github_secret = os.getenv("OAUTH_GITHUB_CLIENT_SECRET")
        
        # If credentials provided, register provider
        if github_id and github_secret:
            register_oauth_provider(
                engine,
                name="github",
                display_name="GitHub",
                client_id=github_id,
                client_secret=github_secret,
                authorize_url="https://github.com/login/oauth/authorize",
                token_url="https://github.com/login/oauth/access_token",
                user_info_url="https://api.github.com/user",
                scope="user:email",
#                redirect_uri="http://127.0.0.1:5000/auth/oauth/callback/github"
            )
            enable_oauth_provider(engine, "github")
            print("✅ GitHub OAuth enabled")
        else:
            print("⚠️  GitHub OAuth credentials not found in environment variables")
            print("   To enable GitHub OAuth:")
            print("   1. Set OAUTH_GITHUB_CLIENT_ID environment variable")
            print("   2. Set OAUTH_GITHUB_CLIENT_SECRET environment variable")
            print("   3. Restart the application")
    
    # Google OAuth (example - commented out)
    # if os.getenv("OAUTH_GOOGLE_ENABLED", "false").lower() == "true":
    #     google_id = os.getenv("OAUTH_GOOGLE_CLIENT_ID")
    #     google_secret = os.getenv("OAUTH_GOOGLE_CLIENT_SECRET")
    #     
    #     if google_id and google_secret:
    #         register_oauth_provider(
    #             engine,
    #             name="google",
    #             display_name="Google",
    #             client_id=google_id,
    #             client_secret=google_secret,
    #             authorize_url="https://accounts.google.com/o/oauth2/v2/auth",
    #             token_url="https://www.googleapis.com/oauth2/v4/token",
    #             user_info_url="https://www.googleapis.com/oauth2/v1/userinfo",
    #             scope="openid email profile"
    #         )
    #         enable_oauth_provider(engine, "google")
    #         print("✅ Google OAuth enabled")


# Initialize OAuth providers
setup_oauth_providers()

# ============================================================
# Create Demo User
# ============================================================

try:
    register(engine, "adam", "TestPass123!@", "adam@example.com")
    print("✅ Demo user created: adam / TestPass123!@")
except:
    pass  # User might already exist

# ============================================================
# Example Routes
# ============================================================

@app.get("/")
def index():
    """Home page"""
    return """
    <!DOCTYPE html>
    <html>
    <head>
        <title>Identitas OAuth Example</title>
        <style>
            body { font-family: Arial; margin: 40px; }
            .container { max-width: 600px; }
            a { display: inline-block; margin: 10px 0; padding: 10px 20px; 
                background: #0078ff; color: white; text-decoration: none; 
                border-radius: 5px; }
            a:hover { background: #005fcc; }
            code { background: #f5f5f5; padding: 2px 6px; }
            .section { margin: 30px 0; padding: 20px; background: #f9f9f9; 
                      border-left: 4px solid #0078ff; }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>Identitas OAuth Example</h1>
            
            <div class="section">
                <h2>Authentication</h2>
                <p>
                    <a href="/auth/login">Login with Username/Password</a>
                </p>
                <p>
                    <a href="/auth/register">Register New Account</a>
                </p>
                <p>
                    Demo user: <code>adam</code> / <code>TestPass123!@</code>
                </p>
            </div>
            
            <div class="section">
                <h2>OAuth Features</h2>
                <p>
                    <a href="/auth/login">See OAuth login options</a>
                </p>
                <p>
                    Available OAuth providers:
                </p>
                <ul id="providers"></ul>
            </div>
            
            <div class="section">
                <h2>User Dashboard</h2>
                <p>
                    <a href="/dashboard">View Dashboard (requires login)</a>
                </p>
            </div>
            
            <div class="section">
                <h2>API Endpoints</h2>
                <ul>
                    <li><code>GET /auth/login</code> - Login page</li>
                    <li><code>GET /auth/register</code> - Registration page</li>
                    <li><code>GET /auth/oauth/login/github</code> - GitHub OAuth login</li>
                    <li><code>GET /auth/oauth/providers</code> - List enabled OAuth providers</li>
                    <li><code>GET /auth/oauth/accounts</code> - List user's OAuth accounts (requires auth)</li>
                    <li><code>POST /auth/oauth/accounts/github/unlink</code> - Unlink OAuth account</li>
                    <li><code>GET /dashboard</code> - User dashboard (requires auth)</li>
                </ul>
            </div>
            
            <div class="section">
                <h2>Environment Variables</h2>
                <p>To enable GitHub OAuth, set these environment variables:</p>
                <ul>
                    <li><code>OAUTH_GITHUB_CLIENT_ID</code> - Your GitHub Client ID</li>
                    <li><code>OAUTH_GITHUB_CLIENT_SECRET</code> - Your GitHub Client Secret</li>
                </ul>
                <p>
                    See <code>OAUTH_GITHUB_SETUP.md</code> for detailed GitHub OAuth setup instructions.
                </p>
            </div>
        </div>
        
        <script>
            // Load available OAuth providers
            fetch('/auth/oauth/providers')
                .then(r => r.json())
                .then(data => {
                    const list = document.getElementById('providers');
                    if (data.providers && data.providers.length > 0) {
                        data.providers.forEach(p => {
                            const li = document.createElement('li');
                            li.textContent = p.display_name + ' (' + p.name + ')';
                            list.appendChild(li);
                        });
                    } else {
                        const li = document.createElement('li');
                        li.textContent = 'No OAuth providers enabled';
                        list.appendChild(li);
                    }
                })
                .catch(err => {
                    const list = document.getElementById('providers');
                    const li = document.createElement('li');
                    li.textContent = 'Error loading providers';
                    list.appendChild(li);
                });
        </script>
    </body>
    </html>
    """


@app.get("/dashboard")
@require_session
def dashboard(user_id):
    """User dashboard"""
    from Identitas.provider.models.user import User
    from sqlalchemy.orm import Session as DBSession
    
    try:
        with DBSession(engine) as session:
            user = session.query(User).filter_by(id=user_id).first()
            
            if not user:
                return "User not found", 404
            
            # Get OAuth accounts
            oauth_accounts = get_user_oauth_accounts(engine, user_id)
            
            # Get permissions (if RBAC enabled)
            permissions = get_user_permissions_summary(engine, user_id)
            
            oauth_html = ""
            if oauth_accounts:
                oauth_html = "<h3>Connected OAuth Accounts:</h3><ul>"
                for acc in oauth_accounts:
                    oauth_html += f"<li>{acc.provider_name}: {acc.provider_email or acc.provider_username}</li>"
                oauth_html += "</ul>"
            else:
                oauth_html = "<p>No OAuth accounts connected</p>"
            
            permissions_html = ""
            if permissions:
                permissions_html = "<h3>Your Permissions:</h3><ul>"
                for resource, actions in permissions.items():
                    permissions_html += f"<li>{resource}: {', '.join(actions)}</li>"
                permissions_html += "</ul>"
            
            return f"""
            <!DOCTYPE html>
            <html>
            <head>
                <title>Dashboard</title>
                <style>
                    body {{ font-family: Arial; margin: 40px; }}
                    .section {{ margin: 20px 0; padding: 20px; background: #f9f9f9; 
                              border-left: 4px solid #0078ff; }}
                    a {{ color: #0078ff; text-decoration: none; }}
                    a:hover {{ text-decoration: underline; }}
                </style>
            </head>
            <body>
                <h1>Welcome, {user.username}!</h1>
                
                <div class="section">
                    <h2>User Information</h2>
                    <p><strong>User ID:</strong> {user.id}</p>
                    <p><strong>Username:</strong> {user.username}</p>
                    <p><strong>Email:</strong> {user.email or 'Not set'}</p>
                </div>
                
                <div class="section">
                    <h2>OAuth Accounts</h2>
                    {oauth_html}
                    <p><a href="/auth/login">Connect another OAuth provider</a></p>
                </div>
                
                <div class="section">
                    {permissions_html}
                </div>
                
                <div class="section">
                    <p><a href="/auth/logout">Logout</a></p>
                </div>
            </body>
            </html>
            """
    except Exception as e:
        return f"Error: {str(e)}", 500


# ============================================================
# Error Handlers
# ============================================================

@app.errorhandler(404)
def not_found(error):
    return "<h1>404 - Not Found</h1>", 404


@app.errorhandler(500)
def server_error(error):
    return "<h1>500 - Server Error</h1>", 500


# ============================================================
# Run Application
# ============================================================

if __name__ == "__main__":
    print("""
    ============================================================
    Identitas OAuth Flask Application
    ============================================================
    
    Features:
    ✅ Traditional username/password authentication
    ✅ OAuth authentication (GitHub and more)
    ✅ Automatic user account creation from OAuth
    ✅ Multiple OAuth provider support
    ✅ Account linking
    
    Available URLs:
    - Home: http://localhost:5000/
    - Login: http://localhost:5000/auth/login
    - Register: http://localhost:5000/auth/register
    - Dashboard: http://localhost:5000/dashboard (requires login)
    
    OAuth Providers:
    """ + ", ".join([p.display_name for p in list_enabled_oauth_providers(engine)]) or "None configured" + """
    
    To enable GitHub OAuth:
    1. Create GitHub OAuth app at https://github.com/settings/developers
    2. Set environment variables:
       export OAUTH_GITHUB_CLIENT_ID="your_id"
       export OAUTH_GITHUB_CLIENT_SECRET="your_secret"
    3. Restart this application
    
    Demo User:
    Username: adam
    Password: TestPass123!@
    
    For GitHub OAuth setup instructions, see: OAUTH_GITHUB_SETUP.md
    For complete documentation, see: OAUTH_DOCUMENTATION.md
    
    ============================================================
    """)
    
    app.run(debug=True)
