import streamlit as st
import hashlib
import psycopg2
import psycopg2.extras
import os
from datetime import datetime
from version import get_version_badge, format_version_display

def get_db_connection():
    """Get PostgreSQL database connection"""
    return psycopg2.connect(os.environ['DATABASE_URL'])

def hash_password(password):
    """Hash password using SHA-256"""
    return hashlib.sha256(password.encode()).hexdigest()

def init_auth_tables():
    """Initialize authentication tables"""
    conn = get_db_connection()
    cursor = conn.cursor()
    
    # Create users table
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS users (
            id SERIAL PRIMARY KEY,
            username VARCHAR(50) UNIQUE NOT NULL,
            password_hash VARCHAR(64) NOT NULL,
            role VARCHAR(20) NOT NULL CHECK (role IN ('admin', 'staff')),
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            last_login TIMESTAMP,
            is_active BOOLEAN DEFAULT TRUE
        )
    """)
    
    # Create default admin user if not exists
    cursor.execute("SELECT COUNT(*) FROM users WHERE username = 'admin'")
    result = cursor.fetchone()
    if result and result[0] == 0:
        admin_password_hash = hash_password('admin123')
        cursor.execute("""
            INSERT INTO users (username, password_hash, role)
            VALUES ('admin', %s, 'admin')
        """, (admin_password_hash,))
        
        # Create default staff user
        staff_password_hash = hash_password('staff123')
        cursor.execute("""
            INSERT INTO users (username, password_hash, role)
            VALUES ('staff', %s, 'staff')
        """, (staff_password_hash,))
    
    conn.commit()
    cursor.close()
    conn.close()

def authenticate_user(username, password):
    """Authenticate user credentials"""
    conn = get_db_connection()
    cursor = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
    
    password_hash = hash_password(password)
    cursor.execute("""
        SELECT id, username, role, is_active
        FROM users
        WHERE username = %s AND password_hash = %s AND is_active = TRUE
    """, (username, password_hash))
    
    user = cursor.fetchone()
    
    if user:
        # Update last login
        cursor.execute("""
            UPDATE users SET last_login = CURRENT_TIMESTAMP
            WHERE id = %s
        """, (user['id'],))
        conn.commit()
    
    cursor.close()
    conn.close()
    return user

def create_user(username, password, role):
    """Create a new user"""
    conn = get_db_connection()
    cursor = conn.cursor()
    
    try:
        password_hash = hash_password(password)
        cursor.execute("""
            INSERT INTO users (username, password_hash, role)
            VALUES (%s, %s, %s)
        """, (username, password_hash, role))
        conn.commit()
        return True
    except psycopg2.IntegrityError:
        return False
    finally:
        cursor.close()
        conn.close()

def get_all_users():
    """Get all users"""
    conn = get_db_connection()
    cursor = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
    cursor.execute("""
        SELECT id, username, role, created_at, last_login, is_active
        FROM users
        ORDER BY created_at DESC
    """)
    users = cursor.fetchall()
    cursor.close()
    conn.close()
    return users

def update_user_status(user_id, is_active):
    """Update user active status"""
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute("""
        UPDATE users SET is_active = %s
        WHERE id = %s
    """, (is_active, user_id))
    conn.commit()
    cursor.close()
    conn.close()

def change_password(username, old_password, new_password):
    """Change user password"""
    conn = get_db_connection()
    cursor = conn.cursor()
    
    old_password_hash = hash_password(old_password)
    new_password_hash = hash_password(new_password)
    
    cursor.execute("""
        UPDATE users SET password_hash = %s
        WHERE username = %s AND password_hash = %s
    """, (new_password_hash, username, old_password_hash))
    
    success = cursor.rowcount > 0
    conn.commit()
    cursor.close()
    conn.close()
    return success

def login_form():
    """Display login form"""
    # Title with version badge
    col1, col2 = st.columns([4, 1])
    with col1:
        st.title("🔐 SIM Analytics - Login")
    with col2:
        st.markdown(get_version_badge(), unsafe_allow_html=True)
    
    with st.form("login_form"):
        username = st.text_input("Username")
        password = st.text_input("Password", type="password")
        
        if st.form_submit_button("Login"):
            if username and password:
                user = authenticate_user(username, password)
                if user:
                    st.session_state.authenticated = True
                    st.session_state.user = user
                    st.success("Login successful!")
                    st.rerun()
                else:
                    st.error("Invalid username or password")
            else:
                st.error("Please enter both username and password")
    
    # Add Telkom Radius Server text at bottom with version
    st.markdown("---")
    col1, col2 = st.columns([3, 1])
    with col1:
        st.markdown("**Access the Telkom Radius Server**")
    with col2:
        st.markdown(f"*{format_version_display()}*", help="Application Version")

def logout():
    """Logout user"""
    st.session_state.authenticated = False
    st.session_state.user = None
    st.rerun()

def check_permission(required_role=None):
    """Check if user has required permission"""
    if not st.session_state.get('authenticated', False):
        return False
    
    if required_role is None:
        return True
    
    user_role = st.session_state.user['role']
    
    if required_role == 'admin':
        return user_role == 'admin'
    elif required_role == 'staff':
        return user_role in ['admin', 'staff']
    
    return False

def show_user_management():
    """Show user management interface (admin only)"""
    if not check_permission('admin'):
        st.error("Access denied. Admin privileges required.")
        return
    
    st.header("👥 User Management")
    
    # Add new user
    with st.expander("Add New User"):
        with st.form("add_user"):
            new_username = st.text_input("Username")
            new_password = st.text_input("Password", type="password")
            new_role = st.selectbox("Role", ["staff", "admin"])
            
            if st.form_submit_button("Create User"):
                if new_username and new_password:
                    if create_user(new_username, new_password, new_role):
                        st.success(f"User '{new_username}' created successfully!")
                    else:
                        st.error("Username already exists")
                else:
                    st.error("Please fill in all fields")
    
    # Display existing users
    st.subheader("Existing Users")
    users = get_all_users()
    
    for user in users:
        with st.expander(f"{user['username']} ({user['role']})"):
            col1, col2, col3 = st.columns(3)
            with col1:
                st.write(f"**Role:** {user['role']}")
            with col2:
                st.write(f"**Created:** {user['created_at'].strftime('%Y-%m-%d') if user['created_at'] else 'N/A'}")
            with col3:
                st.write(f"**Last Login:** {user['last_login'].strftime('%Y-%m-%d %H:%M') if user['last_login'] else 'Never'}")
            
            # Toggle active status
            current_status = user['is_active']
            new_status = st.checkbox(
                "Active", 
                value=current_status, 
                key=f"status_{user['id']}"
            )
            
            if new_status != current_status:
                update_user_status(user['id'], new_status)
                st.success(f"User status updated")
                st.rerun()

def show_change_password():
    """Show change password form"""
    st.header("🔑 Change Password")
    
    with st.form("change_password"):
        old_password = st.text_input("Current Password", type="password")
        new_password = st.text_input("New Password", type="password")
        confirm_password = st.text_input("Confirm New Password", type="password")
        
        if st.form_submit_button("Change Password"):
            if old_password and new_password and confirm_password:
                if new_password == confirm_password:
                    if change_password(st.session_state.user['username'], old_password, new_password):
                        st.success("Password changed successfully!")
                    else:
                        st.error("Current password is incorrect")
                else:
                    st.error("New passwords do not match")
            else:
                st.error("Please fill in all fields")

def init_auth():
    """Initialize authentication system"""
    init_auth_tables()
    
    if 'authenticated' not in st.session_state:
        st.session_state.authenticated = False
    if 'user' not in st.session_state:
        st.session_state.user = None

def require_auth():
    """Require authentication to access the application"""
    init_auth()
    
    if not st.session_state.get('authenticated', False):
        login_form()
        return False
    
    return True

def show_user_info():
    """Show current user information in sidebar"""
    if st.session_state.get('authenticated', False):
        user = st.session_state.user
        st.sidebar.write(f"**Logged in as:** {user['username']}")
        st.sidebar.write(f"**Role:** {user['role'].title()}")
        
        if st.sidebar.button("Logout"):
            logout()