from fastapi import FastAPI, APIRouter, HTTPException, Request, Response, Depends, File, UploadFile
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from dotenv import load_dotenv
from starlette.middleware.cors import CORSMiddleware
from motor.motor_asyncio import AsyncIOMotorClient
import os
import logging
from pathlib import Path
from pydantic import BaseModel, Field, EmailStr
from typing import List, Optional, Dict, Any
import uuid
from datetime import datetime, timezone, timedelta
import requests
import json
import hashlib
import bcrypt
from passlib.context import CryptContext
import shutil
import base64
import stripe
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from fastapi_mail import FastMail, MessageSchema, ConnectionConfig
import asyncio
from typing import Set
from fastapi import WebSocket, WebSocketDisconnect
from datetime import datetime, timezone, timedelta

# Payment system imports
from emergentintegrations.payments.stripe.checkout import StripeCheckout, CheckoutSessionResponse, CheckoutStatusResponse, CheckoutSessionRequest

ROOT_DIR = Path(__file__).parent
load_dotenv(ROOT_DIR / '.env')

# MongoDB connection
mongo_url = os.environ['MONGO_URL']
client = AsyncIOMotorClient(mongo_url)
db = client[os.environ['DB_NAME']]

# Create the main app without a prefix
app = FastAPI()

limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
app.add_exception_handler(429, _rate_limit_exceeded_handler)

# Create a router with the /api prefix
api_router = APIRouter(prefix="/api")

# Email configuration
email_conf = ConnectionConfig(
    MAIL_USERNAME=os.environ.get('MAIL_USERNAME'),
    MAIL_PASSWORD=os.environ.get('MAIL_PASSWORD'),
    MAIL_FROM=os.environ.get('MAIL_FROM', 'noreply@queensmountain.com'),
    MAIL_PORT=int(os.environ.get('MAIL_PORT', 587)),
    MAIL_SERVER=os.environ.get('MAIL_SERVER'),
    MAIL_FROM_NAME="Queens Mountain",
    MAIL_TLS=True,
    MAIL_SSL=False,
    USE_CREDENTIALS=True,
    VALIDATE_CERTS=True
)

fm = FastMail(email_conf)

# Password hashing
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
security = HTTPBearer(auto_error=False)

# File upload directory
UPLOAD_DIR = Path("uploads")
UPLOAD_DIR.mkdir(exist_ok=True)

# Models
class User(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    email: EmailStr
    name: str
    user_type: str  # "reader" or "writer"
    profile_image: Optional[str] = None
    password: Optional[str] = None  # Include password for storage
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    is_active: bool = True

class UserResponse(BaseModel):
    id: str
    email: EmailStr
    name: str
    user_type: str
    profile_image: Optional[str] = None
    created_at: datetime
    is_active: bool

class ReaderProfile(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    user_id: str
    bio: Optional[str] = None
    interests: List[str] = []
    favorite_books: List[str] = []
    following_writers: List[str] = []
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class WriterProfile(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    user_id: str
    bio: Optional[str] = None
    tagline: Optional[str] = None  # "Creating Epic Fantasy Adventures"
    header_image: Optional[str] = None
    social_links: Dict[str, str] = {}
    patreon_link: Optional[str] = None
    books: List[str] = []
    subscriber_count: int = 0
    total_posts: int = 0
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class SubscriptionTier(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    writer_id: str
    name: str  # "Basic Supporter", "Premium Fan", etc.
    description: str
    price: float  # Monthly price
    benefits: List[str] = []  # List of benefits for this tier
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class Chapter(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    writer_id: str
    book_title: str
    chapter_number: int
    title: str
    content: str
    is_free: bool = False  # Free chapters vs paid
    tier_required: Optional[str] = None  # Which subscription tier required
    file_attachments: List[str] = []  # PDF, EPUB, DOCX files
    likes: int = 0
    comments: int = 0
    published_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class BlogPost(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    writer_id: str
    title: str
    content: str
    is_newsletter: bool = False
    file_attachments: List[str] = []
    likes: int = 0
    comments: int = 0
    published_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class Subscription(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    reader_id: str
    writer_id: str
    tier_id: str
    is_active: bool = True
    started_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    next_billing: datetime

class BookReview(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    reader_id: str
    writer_id: str
    chapter_id: Optional[str] = None  # Can review individual chapters
    book_title: str
    content: str
    rating: int  # 1-5 stars
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

# New Models for Landing Page Customization
class LandingPageContent(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    hero_title: str = "Welcome to Queens Mountain"
    hero_subtitle: str = "A premium platform where writers share their stories and readers discover amazing content"
    hero_cta_text: str = "Get Started"
    hero_background_image: Optional[str] = None
    feature1_title: str = "For Readers"
    feature1_description: str = "Discover incredible stories, follow your favorite writers, and share reviews"
    feature1_icon: str = "BookOpen"
    feature2_title: str = "For Writers"
    feature2_description: str = "Share your stories, build an audience, and earn from your passion"
    feature2_icon: str = "PenTool"
    feature3_title: str = "Community"
    feature3_description: str = "Join a vibrant community where stories come alive"
    feature3_icon: str = "Users"
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

# Forum Models
class ForumCategory(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    name: str
    description: str
    color: str = "#ffffff"  # Category color
    is_active: bool = True
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class ForumTopic(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    category_id: str
    user_id: str
    title: str
    content: str
    is_pinned: bool = False
    is_locked: bool = False
    views: int = 0
    replies: int = 0
    last_reply_at: Optional[datetime] = None
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class ForumReply(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    topic_id: str
    user_id: str
    content: str
    likes: int = 0
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class SiteSettings(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    site_name: str = "Queens Mountain"
    background_image: Optional[str] = None
    panel_opacity: int = 20  # Panel opacity percentage (0-100)
    background_color: str = "#000000"
    header_logo: Optional[str] = None
    header_color: str = "#1a1a1a"
    sidebar_color: str = "#333333"
    footer_color: str = "#1a1a1a"
    primary_color: str = "#ffffff"
    secondary_color: str = "#cccccc"
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class AuthSession(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    user_id: str
    session_token: str
    expires_at: datetime
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

# Create models
class UserCreate(BaseModel):
    email: EmailStr
    name: str
    password: str
    user_type: str

class UserLogin(BaseModel):
    email: EmailStr
    password: str

class UserUpdate(BaseModel):
    name: Optional[str] = None
    profile_image: Optional[str] = None
    header_image: Optional[str] = None
    background_image: Optional[str] = None
    header_position: Optional[str] = None
    background_position: Optional[str] = None
    bio: Optional[str] = None
    location: Optional[str] = None
    genre_preferences: Optional[List[str]] = None
    social_links: Optional[Dict[str, str]] = None

class NewsPage(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    title: str = "Latest News"
    content: str = "Stay updated with the latest news and announcements from Queens Mountain."
    featured_article: Optional[str] = None
    announcements: List[str] = Field(default_factory=list)
    last_updated: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class NewsPageUpdate(BaseModel):
    title: Optional[str] = None
    content: Optional[str] = None
    featured_article: Optional[str] = None
    announcements: Optional[List[str]] = None

class AboutPageUpdate(BaseModel):
    title: Optional[str] = None
    content: Optional[str] = None
    mission: Optional[str] = None
    vision: Optional[str] = None
    team_info: Optional[str] = None

class AboutPage(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    title: str = "About Queens Mountain"
    content: str = "Welcome to Queens Mountain, a premium platform for writers and readers to connect and share amazing stories."
    mission: str = "Our mission is to connect writers and readers in meaningful ways."
    vision: str = "To become the premier storytelling platform worldwide."
    team_info: str = "Our team is passionate about literature and technology."
    last_updated: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class LegalPage(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    page_type: str  # "about", "terms", "privacy"
    title: str
    content: str
    is_active: bool = True
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class SiteSettingsUpdate(BaseModel):
    site_name: Optional[str] = None
    background_image: Optional[str] = None
    panel_opacity: Optional[int] = None
    background_color: Optional[str] = None
    header_logo: Optional[str] = None
    header_color: Optional[str] = None
    sidebar_color: Optional[str] = None
    footer_color: Optional[str] = None
    primary_color: Optional[str] = None
    secondary_color: Optional[str] = None

class LandingPageUpdate(BaseModel):
    hero_title: Optional[str] = None
    hero_subtitle: Optional[str] = None
    hero_cta_text: Optional[str] = None
    hero_background_image: Optional[str] = None
    feature1_title: Optional[str] = None
    feature1_description: Optional[str] = None
    feature1_icon: Optional[str] = None
    feature2_title: Optional[str] = None
    feature2_description: Optional[str] = None
    feature2_icon: Optional[str] = None
    feature3_title: Optional[str] = None
    feature3_description: Optional[str] = None
    feature3_icon: Optional[str] = None

class WriterProfileUpdate(BaseModel):
    bio: Optional[str] = None
    tagline: Optional[str] = None
    header_image: Optional[str] = None
    social_links: Optional[Dict[str, str]] = None
    patreon_link: Optional[str] = None

class ChapterCreate(BaseModel):
    book_title: str
    chapter_number: int
    title: str
    content: str
    is_free: bool = False
    tier_required: Optional[str] = None

class BlogPostCreate(BaseModel):
    title: str
    content: str
    is_newsletter: bool = False

class SubscriptionTierCreate(BaseModel):
    name: str
    description: str
    price: float
    benefits: List[str] = []

class ReviewCreate(BaseModel):
    writer_id: str
    chapter_id: Optional[str] = None
    book_title: str
    content: str
    rating: int

class ForumTopicCreate(BaseModel):
    category_id: str
    title: str
    content: str

class ForumReplyCreate(BaseModel):
    topic_id: str
    content: str

class ForumCategoryCreate(BaseModel):
    name: str
    description: str
    color: str = "#ffffff"

# Payment Models
class PaymentTransaction(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    session_id: str
    user_id: Optional[str] = None
    user_email: Optional[str] = None
    amount: float
    currency: str = "usd"
    payment_type: str  # "subscription", "chapter", "tip", "premium_membership"
    target_id: Optional[str] = None  # writer_id, chapter_id, etc.
    metadata: Optional[Dict[str, str]] = None
    payment_status: str = "pending"  # "pending", "paid", "failed", "expired"
    stripe_session_id: Optional[str] = None
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class SubscriptionTier(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    writer_id: str
    name: str
    description: str
    price: float
    currency: str = "usd"
    benefits: List[str] = []
    stripe_price_id: Optional[str] = None
    is_active: bool = True
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class UserSubscription(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    user_id: str
    writer_id: str
    tier_id: str
    stripe_subscription_id: Optional[str] = None
    status: str = "active"  # "active", "cancelled", "expired"
    current_period_start: datetime
    current_period_end: datetime
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class PaymentPackage(BaseModel):
    id: str
    name: str
    amount: float
    currency: str = "usd"
    description: str
    type: str  # "subscription", "chapter", "tip", "premium"

# Payment Request Models
class CheckoutRequest(BaseModel):
    package_id: str
    target_id: Optional[str] = None  # writer_id, chapter_id, etc.
    origin_url: str
    metadata: Optional[Dict[str, str]] = None

class TipRequest(BaseModel):
    writer_id: str
    amount: float
    message: Optional[str] = None
    origin_url: str

# Predefined payment packages (server-side only for security)
PAYMENT_PACKAGES = {
    # Writer Subscription Tiers
    "writer_basic": PaymentPackage(
        id="writer_basic",
        name="Basic Support",
        amount=5.00,
        description="Basic monthly support for writer",
        type="subscription"
    ),
    "writer_premium": PaymentPackage(
        id="writer_premium", 
        name="Premium Support",
        amount=15.00,
        description="Premium monthly support with exclusive content",
        type="subscription"
    ),
    "writer_vip": PaymentPackage(
        id="writer_vip",
        name="VIP Support", 
        amount=30.00,
        description="VIP monthly support with all perks",
        type="subscription"
    ),
    
    # Chapter Purchases
    "chapter_single": PaymentPackage(
        id="chapter_single",
        name="Single Chapter",
        amount=2.99,
        description="Purchase access to a single chapter",
        type="chapter"
    ),
    
    # Site Premium Membership
    "site_premium_monthly": PaymentPackage(
        id="site_premium_monthly",
        name="Premium Monthly",
        amount=9.99,
        description="Monthly premium site access",
        type="premium"
    ),
    "site_premium_yearly": PaymentPackage(
        id="site_premium_yearly",
        name="Premium Yearly",
        amount=99.99,
        description="Yearly premium site access (2 months free)",
        type="premium"
    ),
    
    # Tips (custom amounts handled separately)
    "tip_small": PaymentPackage(
        id="tip_small",
        name="Small Tip",
        amount=3.00,
        description="Show appreciation with a small tip",
        type="tip"
    ),
    "tip_medium": PaymentPackage(
        id="tip_medium", 
        name="Medium Tip",
        amount=10.00,
        description="Show appreciation with a medium tip",
        type="tip"
    ),
    "tip_large": PaymentPackage(
        id="tip_large",
        name="Large Tip", 
        amount=25.00,
        description="Show appreciation with a large tip",
        type="tip"
    ),
}

# Withdrawal System Models
class WriterStripeAccount(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    writer_id: str
    stripe_connect_account_id: str
    account_status: str = "pending"  # "pending", "verified", "rejected", "restricted"
    onboarding_completed: bool = False
    charges_enabled: bool = False
    payouts_enabled: bool = False
    requirements: Optional[Dict[str, Any]] = None
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class WithdrawalRequest(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    writer_id: str
    amount: float
    currency: str = "usd"
    status: str = "pending"  # "pending", "processing", "completed", "failed", "cancelled"
    requested_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    processed_at: Optional[datetime] = None
    stripe_transfer_id: Optional[str] = None
    fee_amount: float = 0.0
    net_amount: float = 0.0
    failure_reason: Optional[str] = None
    notes: Optional[str] = None

class WithdrawalSettings(BaseModel):
    writer_id: str
    auto_payout_enabled: bool = False
    auto_payout_threshold: float = 25.00  # Minimum balance for automatic payouts
    payout_schedule: str = "weekly"  # "daily", "weekly", "monthly"
    next_payout_date: Optional[datetime] = None
    notification_preferences: Dict[str, bool] = {
        "email_on_payout": True,
        "email_on_threshold": True,
        "email_on_failure": True
    }

# Request Models for Withdrawal System
class CreateWithdrawalRequest(BaseModel):
    amount: float
    notes: Optional[str] = None

class UpdateWithdrawalSettings(BaseModel):
    auto_payout_enabled: Optional[bool] = None
    auto_payout_threshold: Optional[float] = None
    payout_schedule: Optional[str] = None
    notification_preferences: Optional[Dict[str, bool]] = None

# Social System Models
class FriendRequest(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    sender_id: str
    receiver_id: str
    status: str = "pending"  # "pending", "accepted", "declined", "blocked"
    message: Optional[str] = None
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class Friendship(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    user1_id: str  # Always the lower ID alphabetically for consistency
    user2_id: str  # Always the higher ID alphabetically
    status: str = "active"  # "active", "blocked"
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class DirectMessage(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    conversation_id: str
    sender_id: str
    receiver_id: str
    content: str
    message_type: str = "text"  # "text", "image", "file"
    media_url: Optional[str] = None
    is_read: bool = False
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    expires_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc) + timedelta(days=180))  # 6 months

class MessageConversation(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    participants: List[str]  # List of user IDs
    last_message: Optional[str] = None
    last_message_at: Optional[datetime] = None
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

class UserStatus(BaseModel):
    user_id: str
    status: str = "offline"  # "online", "reading", "appear_offline", "offline"
    last_seen: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    current_activity: Optional[str] = None  # "reading: Story Title", etc.

class MessageNotification(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    user_id: str
    type: str  # "friend_request", "message", "friend_accepted"
    sender_id: str
    title: str
    content: str
    is_read: bool = False
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    expires_at: Optional[datetime] = None

class UserPrivacySettings(BaseModel):
    user_id: str
    profile_visibility: str = "public"  # "public", "friends", "private"
    accept_friend_requests: bool = True
    allow_messages_from_strangers: bool = True
    show_online_status: bool = True
    show_reading_activity: bool = True
    email_notifications: bool = True
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

# Request Models for Social System
class SendFriendRequest(BaseModel):
    receiver_id: str
    message: Optional[str] = None

class RespondToFriendRequest(BaseModel):
    request_id: str
    action: str  # "accept", "decline", "block"

class SendMessage(BaseModel):
    receiver_id: str
    content: str
    message_type: str = "text"

class UpdateUserStatus(BaseModel):
    status: str  # "online", "reading", "appear_offline"
    activity: Optional[str] = None

class UpdatePrivacySettings(BaseModel):
    profile_visibility: Optional[str] = None
    accept_friend_requests: Optional[bool] = None
    allow_messages_from_strangers: Optional[bool] = None
    show_online_status: Optional[bool] = None
    show_reading_activity: Optional[bool] = None
    email_notifications: Optional[bool] = None

# Authentication helper
async def get_current_user(request: Request, credentials: HTTPAuthorizationCredentials = Depends(security)):
    # Check cookie first
    session_token = request.cookies.get("session_token")
    
    # Fallback to Authorization header
    if not session_token and credentials:
        session_token = credentials.credentials
    
    if not session_token:
        return None
        
    session = await db.auth_sessions.find_one({"session_token": session_token})
    if not session:
        return None
    
    # Handle timezone-aware datetime comparison
    expires_at = session["expires_at"]
    if isinstance(expires_at, str):
        expires_at = datetime.fromisoformat(expires_at.replace('Z', '+00:00'))
    elif not expires_at.tzinfo:
        expires_at = expires_at.replace(tzinfo=timezone.utc)
        
    if datetime.now(timezone.utc) > expires_at:
        return None
        
    user = await db.users.find_one({"id": session["user_id"]})
    return User(**user) if user else None

# Helper functions
def hash_password(password: str) -> str:
    return pwd_context.hash(password)

def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)

# Auth Routes
@api_router.post("/auth/register")
async def register_user(user_data: UserCreate):
    # Check if user exists
    existing_user = await db.users.find_one({"email": user_data.email})
    if existing_user:
        raise HTTPException(status_code=400, detail="Email already registered")
    
    # Create user
    user_dict = user_data.dict()
    hashed_password = hash_password(user_data.password)
    user_dict["password"] = hashed_password
    user = User(**user_dict)
    
    # Prepare user document for MongoDB
    user_doc = user.dict()
    
    await db.users.insert_one(user_doc)
    
    # Create profile based on user type
    if user.user_type == "reader":
        profile = ReaderProfile(user_id=user.id)
        await db.reader_profiles.insert_one(profile.dict())
    elif user.user_type == "writer":
        profile = WriterProfile(user_id=user.id)
        await db.writer_profiles.insert_one(profile.dict())
    
    return {"message": "User created successfully", "user_id": user.id}

@api_router.post("/auth/login")
async def login_user(user_data: UserLogin, response: Response):
    user = await db.users.find_one({"email": user_data.email})
    if not user or not verify_password(user_data.password, user.get("password", "")):
        raise HTTPException(status_code=401, detail="Invalid credentials")
    
    # Create session
    session_token = str(uuid.uuid4())
    expires_at = datetime.now(timezone.utc) + timedelta(days=7)
    session = AuthSession(
        user_id=user["id"],
        session_token=session_token,
        expires_at=expires_at
    )
    
    await db.auth_sessions.insert_one(session.dict())
    
    # Set cookie
    response.set_cookie(
        "session_token",
        session_token,
        httponly=True,
        secure=False,  # Set to False for development
        samesite="lax",  # Change from none to lax
        max_age=7*24*3600,
        path="/"
    )
    
    # Return user without password
    user_response = UserResponse(**user)
    return {"message": "Login successful", "user": user_response.dict()}

@api_router.post("/auth/google-session")
async def process_google_session(request: Request, response: Response):
    session_id = request.headers.get("X-Session-ID")
    if not session_id:
        raise HTTPException(status_code=400, detail="No session ID provided")
    
    try:
        # Get user data from Emergent auth
        auth_response = requests.get(
            "https://demobackend.emergentagent.com/auth/v1/env/oauth/session-data",
            headers={"X-Session-ID": session_id}
        )
        
        if auth_response.status_code != 200:
            raise HTTPException(status_code=401, detail="Invalid session")
            
        user_data = auth_response.json()
        
        # Check if user exists
        existing_user = await db.users.find_one({"email": user_data["email"]})
        
        if not existing_user:
            # Create new user (default to reader, they can switch later)
            user = User(
                email=user_data["email"],
                name=user_data["name"],
                user_type="reader",
                profile_image=user_data.get("picture")
            )
            await db.users.insert_one(user.dict())
            
            # Create reader profile
            profile = ReaderProfile(user_id=user.id)
            await db.reader_profiles.insert_one(profile.dict())
        else:
            user = User(**existing_user)
        
        # Create session with the provided session_token
        expires_at = datetime.now(timezone.utc) + timedelta(days=7)
        session = AuthSession(
            user_id=user.id,
            session_token=user_data["session_token"],
            expires_at=expires_at
        )
        
        await db.auth_sessions.insert_one(session.dict())
        
        # Set cookie
        response.set_cookie(
            "session_token",
            user_data["session_token"],
            httponly=True,
            secure=False,  # Set to False for development
            samesite="lax",  # Change from none to lax
            max_age=7*24*3600,
            path="/"
        )
        
        return {"message": "Authentication successful", "user": UserResponse(**user.dict()).dict()}
        
    except requests.RequestException:
        raise HTTPException(status_code=503, detail="Authentication service unavailable")
    except HTTPException:
        raise  # Re-raise HTTP exceptions as they are
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Authentication failed: {str(e)}")

@api_router.get("/auth/me")
async def get_current_user_info(request: Request):
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    return UserResponse(**user.dict()).dict()

@api_router.post("/auth/logout")
async def logout_user(request: Request, response: Response):
    session_token = request.cookies.get("session_token")
    if session_token:
        await db.auth_sessions.delete_one({"session_token": session_token})
        response.delete_cookie("session_token", path="/")
    return {"message": "Logged out successfully"}

# Landing Page Content Routes
@api_router.get("/content/landing-page")
async def get_landing_page_content():
    content = await db.landing_page_content.find_one()
    if not content:
        # Create default content
        default_content = LandingPageContent()
        await db.landing_page_content.insert_one(default_content.dict())
        return Response(
            content=default_content.json(),
            media_type="application/json",
            headers={"Cache-Control": "public, max-age=300"}  # Cache for 5 minutes
        )
    landing_content = LandingPageContent(**content)
    return Response(
        content=landing_content.json(),
        media_type="application/json",
        headers={"Cache-Control": "public, max-age=300"}
    )

@api_router.put("/admin/landing-page")
async def update_landing_page_content(content_update: LandingPageUpdate, request: Request):
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # For MVP, any authenticated user can update content (add admin check later)
    
    update_data = {k: v for k, v in content_update.dict().items() if v is not None}
    update_data["updated_at"] = datetime.now(timezone.utc)
    
    existing_content = await db.landing_page_content.find_one()
    if existing_content:
        await db.landing_page_content.update_one({}, {"$set": update_data})
    else:
        new_content = LandingPageContent(**update_data)
        await db.landing_page_content.insert_one(new_content.dict())
    
    return {"message": "Landing page content updated successfully"}

# Forum Routes
@api_router.get("/forum/categories")
async def get_forum_categories():
    categories = await db.forum_categories.find({"is_active": True}).to_list(length=None)
    return [ForumCategory(**cat).dict() for cat in categories]

@api_router.post("/admin/forum/categories")
async def create_forum_category(category_data: ForumCategoryCreate, request: Request):
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    category = ForumCategory(**category_data.dict())
    await db.forum_categories.insert_one(category.dict())
    return {"message": "Forum category created successfully", "category_id": category.id}

@api_router.get("/forum/categories/{category_id}/topics")
async def get_forum_topics(category_id: str, skip: int = 0, limit: int = 20):
    topics = await db.forum_topics.find({"category_id": category_id}).skip(skip).limit(limit).sort("created_at", -1).to_list(length=None)
    
    # Enrich with user data
    enriched_topics = []
    for topic in topics:
        user = await db.users.find_one({"id": topic["user_id"]})
        topic_data = ForumTopic(**topic).dict()
        topic_data["user"] = UserResponse(**user).dict() if user else None
        enriched_topics.append(topic_data)
    
    return enriched_topics

@api_router.post("/forum/topics")
async def create_forum_topic(topic_data: ForumTopicCreate, request: Request):
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    topic = ForumTopic(user_id=user.id, **topic_data.dict())
    await db.forum_topics.insert_one(topic.dict())
    return {"message": "Forum topic created successfully", "topic_id": topic.id}

@api_router.get("/forum/topics/{topic_id}")
async def get_forum_topic_with_replies(topic_id: str):
    # Get topic
    topic = await db.forum_topics.find_one({"id": topic_id})
    if not topic:
        raise HTTPException(status_code=404, detail="Topic not found")
    
    # Increment view count
    await db.forum_topics.update_one({"id": topic_id}, {"$inc": {"views": 1}})
    
    # Get topic user
    topic_user = await db.users.find_one({"id": topic["user_id"]})
    topic_data = ForumTopic(**topic).dict()
    topic_data["user"] = UserResponse(**topic_user).dict() if topic_user else None
    
    # Get replies
    replies = await db.forum_replies.find({"topic_id": topic_id}).sort("created_at", 1).to_list(length=None)
    
    # Enrich replies with user data
    enriched_replies = []
    for reply in replies:
        reply_user = await db.users.find_one({"id": reply["user_id"]})
        reply_data = ForumReply(**reply).dict()
        reply_data["user"] = UserResponse(**reply_user).dict() if reply_user else None
        enriched_replies.append(reply_data)
    
    return {
        "topic": topic_data,
        "replies": enriched_replies
    }

@api_router.post("/forum/replies")
async def create_forum_reply(reply_data: ForumReplyCreate, request: Request):
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    reply = ForumReply(user_id=user.id, **reply_data.dict())
    await db.forum_replies.insert_one(reply.dict())
    
    # Update topic reply count and last reply time
    await db.forum_topics.update_one(
        {"id": reply_data.topic_id},
        {
            "$inc": {"replies": 1},
            "$set": {"last_reply_at": datetime.now(timezone.utc)}
        }
    )
    
    return {"message": "Reply created successfully", "reply_id": reply.id}

# Review Routes
@api_router.post("/reviews")
async def create_review(review_data: ReviewCreate, request: Request):
    user = await get_current_user(request, None)
    if not user or user.user_type != "reader":
        raise HTTPException(status_code=403, detail="Only readers can create reviews")
    
    review = BookReview(reader_id=user.id, **review_data.dict())
    await db.book_reviews.insert_one(review.dict())
    return {"message": "Review created successfully", "review_id": review.id}

@api_router.get("/reviews/top-rated")
async def get_top_rated_content():
    # Get top-rated writers (by average review rating)
    top_writers_pipeline = [
        {"$group": {
            "_id": "$writer_id",
            "avg_rating": {"$avg": "$rating"},
            "review_count": {"$sum": 1}
        }},
        {"$match": {"review_count": {"$gte": 3}}},  # At least 3 reviews
        {"$sort": {"avg_rating": -1}},
        {"$limit": 10}
    ]
    
    top_writers_cursor = db.book_reviews.aggregate(top_writers_pipeline)
    top_writers_data = await top_writers_cursor.to_list(length=None)
    
    # Enrich with writer info
    top_writers = []
    for writer_data in top_writers_data:
        user = await db.users.find_one({"id": writer_data["_id"]})
        profile = await db.writer_profiles.find_one({"user_id": writer_data["_id"]})
        if user and profile:
            top_writers.append({
                "user": UserResponse(**user).dict(),
                "profile": WriterProfile(**profile).dict(),
                "avg_rating": round(writer_data["avg_rating"], 2),
                "review_count": writer_data["review_count"]
            })
    
    # Get top-rated books (by average rating)
    top_books_pipeline = [
        {"$group": {
            "_id": "$book_title",
            "avg_rating": {"$avg": "$rating"},
            "review_count": {"$sum": 1},
            "writer_id": {"$first": "$writer_id"}
        }},
        {"$match": {"review_count": {"$gte": 2}}},  # At least 2 reviews
        {"$sort": {"avg_rating": -1}},
        {"$limit": 10}
    ]
    
    top_books_cursor = db.book_reviews.aggregate(top_books_pipeline)
    top_books_data = await top_books_cursor.to_list(length=None)
    
    # Enrich with writer info
    top_books = []
    for book_data in top_books_data:
        writer = await db.users.find_one({"id": book_data["writer_id"]})
        if writer:
            top_books.append({
                "book_title": book_data["_id"],
                "writer": UserResponse(**writer).dict(),
                "avg_rating": round(book_data["avg_rating"], 2),
                "review_count": book_data["review_count"]
            })
    
    # Get recent reviews
    recent_reviews = await db.book_reviews.find().sort("created_at", -1).limit(10).to_list(length=None)
    enriched_reviews = []
    for review in recent_reviews:
        reader = await db.users.find_one({"id": review["reader_id"]})
        writer = await db.users.find_one({"id": review["writer_id"]})
        review_data = BookReview(**review).dict()
        review_data["reader"] = UserResponse(**reader).dict() if reader else None
        review_data["writer"] = UserResponse(**writer).dict() if writer else None
        enriched_reviews.append(review_data)
    
    return {
        "top_writers": top_writers,
        "top_books": top_books,
        "recent_reviews": enriched_reviews
    }

# Writer Profile Routes
@api_router.get("/writers/{writer_id}/profile")
async def get_writer_public_profile(writer_id: str):
    # Get user info
    user = await db.users.find_one({"id": writer_id, "user_type": "writer"})
    if not user:
        raise HTTPException(status_code=404, detail="Writer not found")
    
    # Get writer profile
    profile = await db.writer_profiles.find_one({"user_id": writer_id})
    if not profile:
        raise HTTPException(status_code=404, detail="Writer profile not found")
    
    # Get subscription tiers
    tiers = await db.subscription_tiers.find({"writer_id": writer_id}).to_list(length=None)
    
    # Get recent chapters and blog posts
    chapters = await db.chapters.find({"writer_id": writer_id}).sort("published_at", -1).limit(10).to_list(length=None)
    blog_posts = await db.blog_posts.find({"writer_id": writer_id}).sort("published_at", -1).limit(5).to_list(length=None)
    
    return {
        "user": UserResponse(**user).dict(),
        "profile": WriterProfile(**profile).dict(),
        "subscription_tiers": [SubscriptionTier(**tier).dict() for tier in tiers],
        "recent_chapters": [Chapter(**chapter).dict() for chapter in chapters],
        "recent_blog_posts": [BlogPost(**post).dict() for post in blog_posts]
    }

@api_router.put("/writers/profile")
async def update_writer_profile(profile_update: WriterProfileUpdate, request: Request):
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Only writers can update writer profiles")
    
    # Update profile
    update_data = {k: v for k, v in profile_update.dict().items() if v is not None}
    
    if update_data:
        await db.writer_profiles.update_one(
            {"user_id": user.id},
            {"$set": update_data}
        )
    
    return {"message": "Profile updated successfully"}

@api_router.post("/writers/subscription-tiers")
async def create_subscription_tier(tier_data: SubscriptionTierCreate, request: Request):
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Only writers can create subscription tiers")
    
    tier = SubscriptionTier(writer_id=user.id, **tier_data.dict())
    await db.subscription_tiers.insert_one(tier.dict())
    
    return {"message": "Subscription tier created successfully", "tier_id": tier.id}

@api_router.post("/writers/chapters")
async def create_chapter(chapter_data: ChapterCreate, request: Request):
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Only writers can create chapters")
    
    chapter = Chapter(writer_id=user.id, **chapter_data.dict())
    await db.chapters.insert_one(chapter.dict())
    
    # Update writer's total posts count
    await db.writer_profiles.update_one(
        {"user_id": user.id},
        {"$inc": {"total_posts": 1}}
    )
    
    return {"message": "Chapter created successfully", "chapter_id": chapter.id}

@api_router.post("/writers/blog-posts")
async def create_blog_post(post_data: BlogPostCreate, request: Request):
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Only writers can create blog posts")
    
    blog_post = BlogPost(writer_id=user.id, **post_data.dict())
    await db.blog_posts.insert_one(blog_post.dict())
    
    # Update writer's total posts count
    await db.writer_profiles.update_one(
        {"user_id": user.id},
        {"$inc": {"total_posts": 1}}
    )
    
    return {"message": "Blog post created successfully", "post_id": blog_post.id}

# Reader/Subscription Routes
@api_router.post("/readers/subscribe/{writer_id}/{tier_id}")
async def subscribe_to_writer(writer_id: str, tier_id: str, request: Request):
    user = await get_current_user(request, None)
    if not user or user.user_type != "reader":
        raise HTTPException(status_code=403, detail="Only readers can subscribe")
    
    # Check if tier exists
    tier = await db.subscription_tiers.find_one({"id": tier_id, "writer_id": writer_id})
    if not tier:
        raise HTTPException(status_code=404, detail="Subscription tier not found")
    
    # Check if already subscribed
    existing_sub = await db.subscriptions.find_one({
        "reader_id": user.id,
        "writer_id": writer_id,
        "is_active": True
    })
    
    if existing_sub:
        raise HTTPException(status_code=400, detail="Already subscribed to this writer")
    
    # Create subscription
    subscription = Subscription(
        reader_id=user.id,
        writer_id=writer_id,
        tier_id=tier_id,
        next_billing=datetime.now(timezone.utc) + timedelta(days=30)
    )
    
    await db.subscriptions.insert_one(subscription.dict())
    
    # Update writer's subscriber count
    await db.writer_profiles.update_one(
        {"user_id": writer_id},
        {"$inc": {"subscriber_count": 1}}
    )
    
    return {"message": "Successfully subscribed to writer"}

@api_router.get("/readers/subscriptions")
async def get_reader_subscriptions(request: Request):
    user = await get_current_user(request, None)
    if not user or user.user_type != "reader":
        raise HTTPException(status_code=403, detail="Only readers can view subscriptions")
    
    subscriptions = await db.subscriptions.find({
        "reader_id": user.id,
        "is_active": True
    }).to_list(length=None)
    
    return [Subscription(**sub).dict() for sub in subscriptions]

# Admin Routes
@api_router.get("/admin/site-settings")
async def get_site_settings():
    settings = await db.site_settings.find_one()
    if not settings:
        # Create default settings
        default_settings = SiteSettings()
        await db.site_settings.insert_one(default_settings.dict())
        return default_settings
    return SiteSettings(**settings)

@api_router.put("/admin/site-settings")
async def update_site_settings(settings_update: SiteSettingsUpdate, request: Request):
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # For MVP, any authenticated user can update settings (add admin check later)
    
    update_data = {k: v for k, v in settings_update.dict().items() if v is not None}
    update_data["updated_at"] = datetime.now(timezone.utc)
    
    existing_settings = await db.site_settings.find_one()
    if existing_settings:
        await db.site_settings.update_one({}, {"$set": update_data})
    else:
        new_settings = SiteSettings(**update_data)
        await db.site_settings.insert_one(new_settings.dict())
    
    return {"message": "Site settings updated successfully"}

# File Upload Routes
@api_router.post("/upload/image")
async def upload_image(file: UploadFile = File(...), request: Request = None):
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    if not file.content_type.startswith('image/'):
        raise HTTPException(status_code=400, detail="File must be an image")
    
    # Create unique filename
    file_extension = file.filename.split('.')[-1]
    unique_filename = f"{uuid.uuid4()}.{file_extension}"
    file_path = UPLOAD_DIR / unique_filename
    
    # Save file
    with open(file_path, "wb") as buffer:
        shutil.copyfileobj(file.file, buffer)
    
    return {"filename": unique_filename, "url": f"/uploads/{unique_filename}"}

# Profile Routes
@api_router.get("/profiles/reader/{user_id}")
async def get_reader_profile(user_id: str):
    profile = await db.reader_profiles.find_one({"user_id": user_id})
    if not profile:
        raise HTTPException(status_code=404, detail="Reader profile not found")
    
    user = await db.users.find_one({"id": user_id})
    return {**User(**user).dict(), **ReaderProfile(**profile).dict()}

@api_router.get("/profiles/writer/{user_id}")
async def get_writer_profile(user_id: str):
    profile = await db.writer_profiles.find_one({"user_id": user_id})
    if not profile:
        raise HTTPException(status_code=404, detail="Writer profile not found")
    
    user = await db.users.find_one({"id": user_id})
    return {**User(**user).dict(), **WriterProfile(**profile).dict()}

@api_router.put("/users/profile")
async def update_user_profile(profile_update: UserUpdate, request: Request):
    """Update user profile information"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Prepare update data, filtering out None values
    update_data = {}
    for field, value in profile_update.dict(exclude_unset=True).items():
        if value is not None:
            update_data[field] = value
    
    if update_data:
        # Update the user document
        await db.users.update_one(
            {"id": user.id},
            {"$set": update_data}
        )
        
        # Also update the corresponding profile collection based on user type
        if user.user_type == "reader":
            await db.reader_profiles.update_one(
                {"user_id": user.id},
                {"$set": update_data},
                upsert=True
            )
        elif user.user_type == "writer":
            await db.writer_profiles.update_one(
                {"user_id": user.id},
                {"$set": update_data},
                upsert=True
            )
    
    # Return updated user data
    updated_user = await db.users.find_one({"id": user.id})
    return UserResponse(**updated_user).dict()

# Public News endpoint
@api_router.get("/news")
async def get_news():
    """Get news page content - Public access"""
    news_page = await db.news_page.find_one({})
    if not news_page:
        # Create default news page if none exists
        default_news = NewsPage()
        await db.news_page.insert_one(default_news.dict())
        return default_news.dict()
    return NewsPage(**news_page).dict()

# Admin News endpoints
@api_router.get("/admin/news")
async def get_admin_news():
    """Get news page content - Admin access"""
    news_page = await db.news_page.find_one({})
    if not news_page:
        # Create default news page if none exists
        default_news = NewsPage()
        await db.news_page.insert_one(default_news.dict())
        return default_news.dict()
    return NewsPage(**news_page).dict()

@api_router.put("/admin/news")
async def update_news_page(news_update: NewsPageUpdate, request: Request):
    """Update news page content - Admin only"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "admin":
        raise HTTPException(status_code=403, detail="Admin access required")
    
    # Prepare update data
    update_data = {}
    for field, value in news_update.dict(exclude_unset=True).items():
        if value is not None:
            update_data[field] = value
    
    if update_data:
        update_data['last_updated'] = datetime.now(timezone.utc)
        
        # Update or create news page
        result = await db.news_page.update_one(
            {},
            {"$set": update_data},
            upsert=True
        )
    
    # Return updated news page
    news_page = await db.news_page.find_one({})
    return NewsPage(**news_page).dict()

@api_router.get("/admin/about-page")
async def get_about_page():
    """Get about page content"""
    about_page = await db.about_page.find_one({})
    if not about_page:
        # Create default about page if none exists
        default_about = AboutPage()
        await db.about_page.insert_one(default_about.dict())
        return default_about.dict()
    return AboutPage(**about_page).dict()

@api_router.put("/admin/about-page")
async def update_about_page(about_update: AboutPageUpdate, request: Request):
    """Update about page content - Admin only"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "admin":
        raise HTTPException(status_code=403, detail="Admin access required")
    
    # Prepare update data
    update_data = {}
    for field, value in about_update.dict(exclude_unset=True).items():
        if value is not None:
            update_data[field] = value
    
    if update_data:
        update_data['last_updated'] = datetime.now(timezone.utc)
        
        # Update or create about page
        result = await db.about_page.update_one(
            {},
            {"$set": update_data},
            upsert=True
        )
    
    # Return updated about page
    about_page = await db.about_page.find_one({})
    return AboutPage(**about_page).dict()

@api_router.get("/")
async def root():
    return {"message": "Queens Mountain API"}

# WebSocket Connection Manager for Real-time Messaging
class ConnectionManager:
    def __init__(self):
        self.active_connections: Dict[str, WebSocket] = {}
        
    async def connect(self, websocket: WebSocket, user_id: str):
        await websocket.accept()
        self.active_connections[user_id] = websocket
        
        # Update user status to online
        await db.user_status.update_one(
            {"user_id": user_id},
            {"$set": {
                "status": "online",
                "last_seen": datetime.now(timezone.utc)
            }},
            upsert=True
        )
        
    def disconnect(self, user_id: str):
        if user_id in self.active_connections:
            del self.active_connections[user_id]
            
    async def send_personal_message(self, message: str, user_id: str):
        if user_id in self.active_connections:
            try:
                await self.active_connections[user_id].send_text(message)
                return True
            except:
                # Connection might be stale, remove it
                self.disconnect(user_id)
                return False
        return False

manager = ConnectionManager()

# Social System API Endpoints

# Friend Request System
@api_router.post("/social/friend-request")
async def send_friend_request(request_data: SendFriendRequest, request: Request):
    """Send a friend request to another user"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Check if receiver exists
    receiver = await db.users.find_one({"id": request_data.receiver_id})
    if not receiver:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Check privacy settings
    privacy_settings = await db.user_privacy_settings.find_one({"user_id": request_data.receiver_id})
    if privacy_settings and not privacy_settings.get("accept_friend_requests", True):
        raise HTTPException(status_code=403, detail="User is not accepting friend requests")
    
    # Check if already friends or request exists
    existing_friendship = await db.friendships.find_one({
        "$or": [
            {"user1_id": min(user.id, request_data.receiver_id), "user2_id": max(user.id, request_data.receiver_id)},
        ]
    })
    if existing_friendship:
        raise HTTPException(status_code=409, detail="Already friends")
    
    existing_request = await db.friend_requests.find_one({
        "$or": [
            {"sender_id": user.id, "receiver_id": request_data.receiver_id, "status": "pending"},
            {"sender_id": request_data.receiver_id, "receiver_id": user.id, "status": "pending"}
        ]
    })
    if existing_request:
        raise HTTPException(status_code=409, detail="Friend request already exists")
    
    # Create friend request
    friend_request = FriendRequest(
        sender_id=user.id,
        receiver_id=request_data.receiver_id,
        message=request_data.message
    )
    
    await db.friend_requests.insert_one(friend_request.dict())
    
    # Create notification
    notification = MessageNotification(
        user_id=request_data.receiver_id,
        type="friend_request",
        sender_id=user.id,
        title="New Friend Request",
        content=f"{user.name} sent you a friend request"
    )
    await db.message_notifications.insert_one(notification.dict())
    
    # Send real-time notification
    await manager.send_personal_message(
        json.dumps({
            "type": "friend_request",
            "sender": user.name,
            "sender_id": user.id,
            "message": request_data.message
        }),
        request_data.receiver_id
    )
    
    return {"message": "Friend request sent successfully"}

@api_router.post("/social/friend-request/respond")
async def respond_to_friend_request(response_data: RespondToFriendRequest, request: Request):
    """Respond to a friend request (accept, decline, block)"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Get the friend request
    friend_request = await db.friend_requests.find_one({
        "id": response_data.request_id,
        "receiver_id": user.id,
        "status": "pending"
    })
    if not friend_request:
        raise HTTPException(status_code=404, detail="Friend request not found")
    
    # Update request status
    await db.friend_requests.update_one(
        {"id": response_data.request_id},
        {"$set": {
            "status": response_data.action + ("ed" if response_data.action != "block" else "ed"),
            "updated_at": datetime.now(timezone.utc)
        }}
    )
    
    if response_data.action == "accept":
        # Create friendship
        friendship = Friendship(
            user1_id=min(user.id, friend_request["sender_id"]),
            user2_id=max(user.id, friend_request["sender_id"])
        )
        await db.friendships.insert_one(friendship.dict())
        
        # Notify sender
        notification = MessageNotification(
            user_id=friend_request["sender_id"],
            type="friend_accepted",
            sender_id=user.id,
            title="Friend Request Accepted",
            content=f"{user.name} accepted your friend request"
        )
        await db.message_notifications.insert_one(notification.dict())
        
        # Send real-time notification
        await manager.send_personal_message(
            json.dumps({
                "type": "friend_accepted",
                "sender": user.name,
                "sender_id": user.id
            }),
            friend_request["sender_id"]
        )
    
    return {"message": f"Friend request {response_data.action}ed successfully"}

@api_router.get("/social/friend-requests")
async def get_friend_requests(request: Request):
    """Get user's friend requests (sent and received)"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Get received requests
    received_requests = await db.friend_requests.find({
        "receiver_id": user.id,
        "status": "pending"
    }).to_list(length=None)
    
    # Get sent requests
    sent_requests = await db.friend_requests.find({
        "sender_id": user.id,
        "status": "pending"
    }).to_list(length=None)
    
    # Enrich with user details
    for req in received_requests:
        sender = await db.users.find_one({"id": req["sender_id"]})
        req["sender"] = UserResponse(**sender).dict() if sender else None
        # Convert MongoDB ObjectId to string if present
        if "_id" in req:
            del req["_id"]
    
    for req in sent_requests:
        receiver = await db.users.find_one({"id": req["receiver_id"]})
        req["receiver"] = UserResponse(**receiver).dict() if receiver else None
        # Convert MongoDB ObjectId to string if present
        if "_id" in req:
            del req["_id"]
    
    return {
        "received": received_requests,
        "sent": sent_requests
    }

@api_router.get("/social/friends")
async def get_friends(request: Request):
    """Get user's friends list"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Get friendships
    friendships = await db.friendships.find({
        "$or": [
            {"user1_id": user.id},
            {"user2_id": user.id}
        ],
        "status": "active"
    }).to_list(length=None)
    
    friends = []
    for friendship in friendships:
        friend_id = friendship["user2_id"] if friendship["user1_id"] == user.id else friendship["user1_id"]
        friend = await db.users.find_one({"id": friend_id})
        
        if friend:
            # Get online status
            status = await db.user_status.find_one({"user_id": friend_id})
            friend_data = UserResponse(**friend).dict()
            friend_data["status"] = status["status"] if status else "offline"
            friend_data["last_seen"] = status["last_seen"] if status else None
            friend_data["friendship_date"] = friendship["created_at"]
            friends.append(friend_data)
    
    return {"friends": friends}

# Direct Messaging System
@api_router.post("/social/messages/send")
async def send_direct_message(message_data: SendMessage, request: Request):
    """Send a direct message to another user"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Check if receiver exists
    receiver = await db.users.find_one({"id": message_data.receiver_id})
    if not receiver:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Check if they are friends
    friendship = await db.friendships.find_one({
        "$or": [
            {"user1_id": min(user.id, message_data.receiver_id), "user2_id": max(user.id, message_data.receiver_id)}
        ],
        "status": "active"
    })
    
    # Check privacy settings for non-friends
    if not friendship:
        privacy_settings = await db.user_privacy_settings.find_one({"user_id": message_data.receiver_id})
        if privacy_settings and not privacy_settings.get("allow_messages_from_strangers", True):
            raise HTTPException(status_code=403, detail="User does not accept messages from non-friends")
    
    # Get or create conversation
    conversation = await db.message_conversations.find_one({
        "participants": {"$all": [user.id, message_data.receiver_id]}
    })
    
    if not conversation:
        conversation = MessageConversation(
            participants=[user.id, message_data.receiver_id]
        )
        await db.message_conversations.insert_one(conversation.dict())
        conversation_id = conversation.id
    else:
        conversation_id = conversation["id"]
    
    # Create message
    message = DirectMessage(
        conversation_id=conversation_id,
        sender_id=user.id,
        receiver_id=message_data.receiver_id,
        content=message_data.content,
        message_type=message_data.message_type
    )
    
    await db.direct_messages.insert_one(message.dict())
    
    # Update conversation
    await db.message_conversations.update_one(
        {"id": conversation_id},
        {"$set": {
            "last_message": message_data.content[:50] + "..." if len(message_data.content) > 50 else message_data.content,
            "last_message_at": datetime.now(timezone.utc),
            "updated_at": datetime.now(timezone.utc)
        }}
    )
    
    # Create notification
    notification = MessageNotification(
        user_id=message_data.receiver_id,
        type="message",
        sender_id=user.id,
        title="New Message",
        content=f"New message from {user.name}"
    )
    await db.message_notifications.insert_one(notification.dict())
    
    # Send real-time message
    await manager.send_personal_message(
        json.dumps({
            "type": "new_message",
            "conversation_id": conversation_id,
            "sender": user.name,
            "sender_id": user.id,
            "content": message_data.content,
            "message_type": message_data.message_type,
            "created_at": message.created_at.isoformat()
        }),
        message_data.receiver_id
    )
    
    return {"message": "Message sent successfully", "conversation_id": conversation_id}

@api_router.get("/social/messages/conversations")
async def get_conversations(request: Request):
    """Get user's message conversations"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Get conversations
    conversations = await db.message_conversations.find({
        "participants": user.id
    }).sort("updated_at", -1).to_list(length=None)
    
    # Enrich with participant details and unread count
    enriched_conversations = []
    for conv in conversations:
        # Find other participant safely
        other_participant_id = None
        for p in conv["participants"]:
            if p != user.id:
                other_participant_id = p
                break
        
        if not other_participant_id:
            continue  # Skip conversations with no other participants
            
        other_user = await db.users.find_one({"id": other_participant_id})
        
        # Count unread messages
        unread_count = await db.direct_messages.count_documents({
            "conversation_id": conv["id"],
            "receiver_id": user.id,
            "is_read": False
        })
        
        if other_user:
            conv_data = MessageConversation(**conv).dict()
            conv_data["other_participant"] = UserResponse(**other_user).dict()
            conv_data["unread_count"] = unread_count
            # Remove MongoDB ObjectId if present
            if "_id" in conv_data:
                del conv_data["_id"]
            enriched_conversations.append(conv_data)
    
    return {"conversations": enriched_conversations}

@api_router.get("/social/messages/conversation/{conversation_id}")
async def get_conversation_messages(conversation_id: str, request: Request, limit: int = 50, offset: int = 0):
    """Get messages from a specific conversation"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Verify user is part of conversation
    conversation = await db.message_conversations.find_one({
        "id": conversation_id,
        "participants": user.id
    })
    if not conversation:
        raise HTTPException(status_code=404, detail="Conversation not found")
    
    # Get messages
    messages = await db.direct_messages.find({
        "conversation_id": conversation_id
    }).sort("created_at", -1).skip(offset).limit(limit).to_list(length=None)
    
    # Mark messages as read
    await db.direct_messages.update_many(
        {
            "conversation_id": conversation_id,
            "receiver_id": user.id,
            "is_read": False
        },
        {"$set": {"is_read": True}}
    )
    
    # Reverse for chronological order
    messages.reverse()
    
    return {"messages": [DirectMessage(**msg).dict() for msg in messages]}

# User Status and Privacy
@api_router.post("/social/status/update")
async def update_user_status(status_data: UpdateUserStatus, request: Request):
    """Update user's online status"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    await db.user_status.update_one(
        {"user_id": user.id},
        {"$set": {
            "status": status_data.status,
            "current_activity": status_data.activity,
            "last_seen": datetime.now(timezone.utc)
        }},
        upsert=True
    )
    
    return {"message": "Status updated successfully"}

@api_router.get("/social/notifications")
async def get_notifications(request: Request, limit: int = 20):
    """Get user's notifications"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    notifications = await db.message_notifications.find({
        "user_id": user.id
    }).sort("created_at", -1).limit(limit).to_list(length=None)
    
    # Enrich with sender details
    for notification in notifications:
        sender = await db.users.find_one({"id": notification["sender_id"]})
        notification["sender"] = UserResponse(**sender).dict() if sender else None
    
    return {"notifications": [MessageNotification(**notif).dict() for notif in notifications]}

@api_router.put("/social/notifications/{notification_id}/read")
async def mark_notification_read(notification_id: str, request: Request):
    """Mark notification as read"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    await db.message_notifications.update_one(
        {"id": notification_id, "user_id": user.id},
        {"$set": {"is_read": True}}
    )
    
    return {"message": "Notification marked as read"}

@api_router.get("/social/notifications/unread-count")
async def get_unread_count(request: Request):
    """Get count of unread notifications and messages"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Count unread notifications
    unread_notifications = await db.message_notifications.count_documents({
        "user_id": user.id,
        "is_read": False
    })
    
    # Count unread messages
    unread_messages = await db.direct_messages.count_documents({
        "receiver_id": user.id,
        "is_read": False
    })
    
    return {
        "unread_notifications": unread_notifications,
        "unread_messages": unread_messages,
        "total_unread": unread_notifications + unread_messages
    }

@api_router.put("/social/privacy-settings")
async def update_privacy_settings(settings: UpdatePrivacySettings, request: Request):
    """Update user's privacy settings"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    # Get existing settings or create new
    existing = await db.user_privacy_settings.find_one({"user_id": user.id})
    
    update_data = {k: v for k, v in settings.dict().items() if v is not None}
    update_data["updated_at"] = datetime.now(timezone.utc)
    
    if existing:
        await db.user_privacy_settings.update_one(
            {"user_id": user.id},
            {"$set": update_data}
        )
    else:
        privacy_settings = UserPrivacySettings(
            user_id=user.id,
            **update_data
        )
        await db.user_privacy_settings.insert_one(privacy_settings.dict())
    
    return {"message": "Privacy settings updated successfully"}

@api_router.get("/social/privacy-settings")
async def get_privacy_settings(request: Request):
    """Get user's privacy settings"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    settings = await db.user_privacy_settings.find_one({"user_id": user.id})
    if not settings:
        # Return default settings
        default_settings = UserPrivacySettings(user_id=user.id)
        return default_settings.dict()
    
    return UserPrivacySettings(**settings).dict()

# WebSocket endpoint for real-time messaging
@api_router.websocket("/social/ws/{user_id}")
async def websocket_endpoint(websocket: WebSocket, user_id: str):
    await manager.connect(websocket, user_id)
    try:
        while True:
            # Keep connection alive and handle incoming messages
            data = await websocket.receive_text()
            # You can add message handling logic here if needed
            await asyncio.sleep(0.1)
    except WebSocketDisconnect:
        manager.disconnect(user_id)
        # Update user status to offline
        await db.user_status.update_one(
            {"user_id": user_id},
            {"$set": {
                "status": "offline",
                "last_seen": datetime.now(timezone.utc)
            }}
        )

# Stories and Stats API endpoints for landing page
@limiter.limit("100/minute")
@api_router.get("/stories")
async def get_stories(limit: int = 10, offset: int = 0):
    """Get popular stories for landing page"""
    try:
        # Ensure limit is positive
        limit = max(1, limit)
        offset = max(0, offset)
        
        # Get stories from chapters collection, aggregating by book_title/writer_id
        pipeline = [
            {
                "$group": {
                    "_id": {
                        "title": "$book_title", 
                        "writer_id": "$writer_id"
                    },
                    "title": {"$first": "$book_title"},
                    "writer_id": {"$first": "$writer_id"},
                    "description": {"$first": "$content"},  # Use content as description
                    "chapters": {"$sum": 1},
                    "total_views": {"$sum": {"$ifNull": ["$likes", 0]}},  # Use likes as views
                    "last_updated": {"$max": "$published_at"}
                }
            },
            {
                "$lookup": {
                    "from": "users",
                    "localField": "writer_id",
                    "foreignField": "id",
                    "as": "author_info"
                }
            },
            {
                "$addFields": {
                    "author": {"$arrayElemAt": ["$author_info.name", 0]},
                    "rating": {"$round": [{"$add": [4.0, {"$multiply": [{"$rand": {}}, 1.0]}]}, 1]}, # Random rating 4.0-5.0
                    "views": "$total_views",
                    "tags": []  # Add empty tags array
                }
            },
            {
                "$project": {
                    "_id": 0,
                    "id": {"$concat": [{"$toString": "$writer_id"}, "-", {"$replaceAll": {"input": "$title", "find": " ", "replacement": "-"}}]},
                    "title": 1,
                    "author": 1,
                    "description": {"$substr": ["$description", 0, 150]},  # Truncate description
                    "rating": 1,
                    "chapters": 1,
                    "views": 1,
                    "tags": {"$ifNull": ["$tags", []]}
                }
            },
            {"$sort": {"views": -1, "rating": -1}},
            {"$skip": offset},
            {"$limit": limit}
        ]
        
        stories_cursor = db.chapters.aggregate(pipeline)
        stories = await stories_cursor.to_list(length=limit)
        
        # Return empty array if no real stories found - production ready
        # This allows the platform to start clean for new users
        
        return {"stories": stories}
        
    except Exception as e:
        logger.error(f"Error fetching stories: {str(e)}")
        # Return empty stories for production - allows clean start
        return {"stories": []}

@api_router.get("/stats")
async def get_site_stats():
    """Get site statistics for landing page and admin dashboard"""
    try:
        # Get user statistics
        total_users = await db.users.count_documents({})
        active_users = await db.users.count_documents({
            "last_login": {"$gte": datetime.now(timezone.utc) - timedelta(days=30)}
        })
        
        # Get user registrations this month
        start_of_month = datetime.now(timezone.utc).replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        new_users_this_month = await db.users.count_documents({
            "created_at": {"$gte": start_of_month}
        })
        
        # Get posts/content statistics
        total_posts = await db.chapters.count_documents({}) + await db.blog_posts.count_documents({})
        total_stories = await db.chapters.distinct("story_title")
        
        # Get earnings from payment transactions
        earnings_pipeline = [
            {"$match": {"status": "completed"}},
            {"$group": {"_id": None, "total": {"$sum": "$amount"}}}
        ]
        earnings_cursor = db.payment_transactions.aggregate(earnings_pipeline)
        earnings_result = await earnings_cursor.to_list(length=1)
        total_earnings = earnings_result[0]["total"] if earnings_result else 0
        
        # Get forum/review statistics
        reported_content = await db.forum_topics.count_documents({"reported": True}) + \
                          await db.reviews.count_documents({"reported": True})
        
        pending_reviews = await db.reviews.count_documents({"status": "pending"})
        
        stats = {
            "totalUsers": total_users,
            "activeUsers": active_users, 
            "newUsersThisMonth": new_users_this_month,
            "totalEarnings": round(total_earnings, 2),
            "totalPosts": total_posts,
            "totalStories": len(total_stories) if total_stories else 0,
            "reportedContent": reported_content,
            "pendingReviews": pending_reviews
        }
        
        return stats
        
    except Exception as e:
        logger.error(f"Error fetching site stats: {str(e)}")
        # Return clean stats for production - start with real zeros
        return {
            "totalUsers": 0,
            "activeUsers": 0, 
            "newUsersThisMonth": 0,
            "totalEarnings": 0.0,
            "totalPosts": 0,
            "totalStories": 0,
            "reportedContent": 0,
            "pendingReviews": 0
        }

# Legal Pages API
@api_router.get("/legal/{page_type}")
async def get_legal_page(page_type: str):
    """Get legal page content (about, terms, privacy)"""
    try:
        if page_type not in ["about", "terms", "privacy"]:
            raise HTTPException(status_code=404, detail="Legal page not found")
            
        page = await db.legal_pages.find_one({"page_type": page_type, "is_active": True})
        if not page:
            raise HTTPException(status_code=404, detail="Legal page not found")
            
        return {
            "id": page["id"],
            "title": page["title"],
            "content": page["content"],
            "updated_at": page["updated_at"]
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

app.include_router(api_router)

# Payment Routes - Comprehensive Stripe Integration
@api_router.get("/payments/packages")
async def get_payment_packages():
    """Get all available payment packages"""
    return {"packages": [pkg.dict() for pkg in PAYMENT_PACKAGES.values()]}

@api_router.get("/payments/packages/{package_type}")
async def get_packages_by_type(package_type: str):
    """Get payment packages filtered by type"""
    filtered_packages = [
        pkg.dict() for pkg in PAYMENT_PACKAGES.values() 
        if pkg.type == package_type
    ]
    return {"packages": filtered_packages}

@api_router.post("/payments/checkout/session")
async def create_payment_session(checkout_request: CheckoutRequest, request: Request):
    """Create Stripe checkout session for any payment type"""
    # Get user if authenticated
    user = await get_current_user(request, None)
    
    # Validate package exists
    if checkout_request.package_id not in PAYMENT_PACKAGES:
        raise HTTPException(status_code=400, detail="Invalid payment package")
    
    package = PAYMENT_PACKAGES[checkout_request.package_id]
    
    # Get Stripe API key
    stripe_api_key = os.environ.get('STRIPE_API_KEY')
    if not stripe_api_key:
        raise HTTPException(status_code=500, detail="Payment system not configured")
    
    try:
        # Initialize Stripe checkout
        host_url = checkout_request.origin_url
        webhook_url = f"{host_url}/api/webhook/stripe"
        stripe_checkout = StripeCheckout(api_key=stripe_api_key, webhook_url=webhook_url)
        
        # Build success and cancel URLs
        success_url = f"{host_url}/payment/success?session_id={{CHECKOUT_SESSION_ID}}"
        cancel_url = f"{host_url}/payment/cancel"
        
        # Prepare metadata
        metadata = {
            "package_id": package.id,
            "package_type": package.type,
            "user_id": user.id if user else "anonymous",
            "user_email": user.email if user else "unknown"
        }
        
        # Add target-specific metadata
        if checkout_request.target_id:
            metadata["target_id"] = checkout_request.target_id
            
        if checkout_request.metadata:
            metadata.update(checkout_request.metadata)
        
        # Create checkout session request
        session_request = CheckoutSessionRequest(
            amount=package.amount,
            currency=package.currency,
            success_url=success_url,
            cancel_url=cancel_url,
            metadata=metadata
        )
        
        # Create Stripe session
        session = await stripe_checkout.create_checkout_session(session_request)
        
        # Store payment transaction
        transaction = PaymentTransaction(
            session_id=session.session_id,
            user_id=user.id if user else None,
            user_email=user.email if user else None,
            amount=package.amount,
            currency=package.currency,
            payment_type=package.type,
            target_id=checkout_request.target_id,
            metadata=metadata,
            payment_status="pending",
            stripe_session_id=session.session_id
        )
        
        await db.payment_transactions.insert_one(transaction.dict())
        
        return {
            "url": session.url,
            "session_id": session.session_id,
            "package": package.dict()
        }
        
    except Exception as e:
        logger.error(f"Payment session creation error: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to create payment session")

@api_router.post("/payments/tip/session")
async def create_tip_session(tip_request: TipRequest, request: Request):
    """Create custom tip payment session"""
    # Get user if authenticated
    user = await get_current_user(request, None)
    
    # Validate amount
    if tip_request.amount < 1.0 or tip_request.amount > 1000.0:
        raise HTTPException(status_code=400, detail="Tip amount must be between $1.00 and $1000.00")
    
    # Validate writer exists
    writer = await db.users.find_one({"id": tip_request.writer_id, "user_type": "writer"})
    if not writer:
        raise HTTPException(status_code=404, detail="Writer not found")
    
    # Get Stripe API key
    stripe_api_key = os.environ.get('STRIPE_API_KEY')
    if not stripe_api_key:
        raise HTTPException(status_code=500, detail="Payment system not configured")
    
    try:
        # Initialize Stripe checkout
        host_url = tip_request.origin_url
        webhook_url = f"{host_url}/api/webhook/stripe"
        stripe_checkout = StripeCheckout(api_key=stripe_api_key, webhook_url=webhook_url)
        
        # Build success and cancel URLs
        success_url = f"{host_url}/payment/success?session_id={{CHECKOUT_SESSION_ID}}"
        cancel_url = f"{host_url}/writer/{tip_request.writer_id}"
        
        # Prepare metadata
        metadata = {
            "payment_type": "tip",
            "writer_id": tip_request.writer_id,
            "writer_name": writer["name"],
            "user_id": user.id if user else "anonymous",
            "user_email": user.email if user else "unknown"
        }
        
        if tip_request.message:
            metadata["message"] = tip_request.message[:500]  # Limit message length
        
        # Create checkout session request
        session_request = CheckoutSessionRequest(
            amount=tip_request.amount,
            currency="usd",
            success_url=success_url,
            cancel_url=cancel_url,
            metadata=metadata
        )
        
        # Create Stripe session
        session = await stripe_checkout.create_checkout_session(session_request)
        
        # Store payment transaction
        transaction = PaymentTransaction(
            session_id=session.session_id,
            user_id=user.id if user else None,
            user_email=user.email if user else None,
            amount=tip_request.amount,
            currency="usd",
            payment_type="tip",
            target_id=tip_request.writer_id,
            metadata=metadata,
            payment_status="pending",
            stripe_session_id=session.session_id
        )
        
        await db.payment_transactions.insert_one(transaction.dict())
        
        return {
            "url": session.url,
            "session_id": session.session_id,
            "writer": {"id": writer["id"], "name": writer["name"]},
            "amount": tip_request.amount
        }
        
    except Exception as e:
        logger.error(f"Tip session creation error: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to create tip session")

@api_router.get("/payments/status/{session_id}")
async def get_payment_status(session_id: str, request: Request):
    """Check payment status and update transaction"""
    # Find transaction
    transaction = await db.payment_transactions.find_one({"session_id": session_id})
    if not transaction:
        raise HTTPException(status_code=404, detail="Payment transaction not found")
    
    # Get Stripe API key
    stripe_api_key = os.environ.get('STRIPE_API_KEY')
    if not stripe_api_key:
        raise HTTPException(status_code=500, detail="Payment system not configured")
    
    try:
        # Initialize Stripe checkout
        stripe_checkout = StripeCheckout(api_key=stripe_api_key, webhook_url="")
        
        # Get checkout status from Stripe
        status_response = await stripe_checkout.get_checkout_status(session_id)
        
        # Update transaction if status changed (prevent duplicate processing)
        if transaction["payment_status"] != status_response.payment_status:
            update_data = {
                "payment_status": status_response.payment_status,
                "updated_at": datetime.now(timezone.utc)
            }
            
            await db.payment_transactions.update_one(
                {"session_id": session_id},
                {"$set": update_data}
            )
            
            # Process successful payment (only once)
            if status_response.payment_status == "paid" and transaction["payment_status"] != "paid":
                await process_successful_payment(transaction, status_response)
        
        return {
            "session_id": session_id,
            "payment_status": status_response.payment_status,
            "status": status_response.status,
            "amount_total": status_response.amount_total,
            "currency": status_response.currency,
            "package_type": transaction.get("payment_type", "unknown")
        }
        
    except Exception as e:
        logger.error(f"Payment status check error: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to check payment status")

@api_router.post("/webhook/stripe")
async def stripe_webhook(request: Request):
    """Handle Stripe webhooks"""
    # Get Stripe API key
    stripe_api_key = os.environ.get('STRIPE_API_KEY')
    if not stripe_api_key:
        raise HTTPException(status_code=500, detail="Payment system not configured")
    
    try:
        # Get webhook body and signature
        body = await request.body()
        signature = request.headers.get("Stripe-Signature")
        
        # Initialize Stripe checkout
        stripe_checkout = StripeCheckout(api_key=stripe_api_key, webhook_url="")
        
        # Handle webhook
        webhook_response = await stripe_checkout.handle_webhook(body, signature)
        
        # Find and update transaction
        transaction = await db.payment_transactions.find_one({"session_id": webhook_response.session_id})
        if transaction:
            # Update payment status
            await db.payment_transactions.update_one(
                {"session_id": webhook_response.session_id},
                {"$set": {
                    "payment_status": webhook_response.payment_status,
                    "updated_at": datetime.now(timezone.utc)
                }}
            )
            
            # Process successful payment
            if webhook_response.payment_status == "paid" and transaction["payment_status"] != "paid":
                await process_successful_payment(transaction, webhook_response)
        
        return {"status": "success"}
        
    except Exception as e:
        logger.error(f"Webhook error: {str(e)}")
        raise HTTPException(status_code=400, detail="Webhook processing failed")

async def process_successful_payment(transaction: dict, payment_details):
    """Process successful payment and grant access"""
    payment_type = transaction.get("payment_type")
    user_id = transaction.get("user_id")
    target_id = transaction.get("target_id")
    
    try:
        if payment_type == "subscription" and user_id and target_id:
            # Create or update writer subscription
            subscription = UserSubscription(
                user_id=user_id,
                writer_id=target_id,
                tier_id=transaction.get("metadata", {}).get("tier_id", "basic"),
                status="active",
                current_period_start=datetime.now(timezone.utc),
                current_period_end=datetime.now(timezone.utc) + timedelta(days=30)
            )
            await db.user_subscriptions.insert_one(subscription.dict())
            
        elif payment_type == "chapter" and user_id and target_id:
            # Grant chapter access
            chapter_access = {
                "id": str(uuid.uuid4()),
                "user_id": user_id,
                "chapter_id": target_id,
                "purchased_at": datetime.now(timezone.utc),
                "access_type": "purchased"
            }
            await db.chapter_access.insert_one(chapter_access)
            
        elif payment_type == "premium" and user_id:
            # Grant premium membership
            premium_end = datetime.now(timezone.utc)
            if "monthly" in transaction.get("metadata", {}).get("package_id", ""):
                premium_end += timedelta(days=30)
            elif "yearly" in transaction.get("metadata", {}).get("package_id", ""):
                premium_end += timedelta(days=365)
                
            premium_membership = {
                "id": str(uuid.uuid4()),
                "user_id": user_id,
                "membership_type": "premium",
                "start_date": datetime.now(timezone.utc),
                "end_date": premium_end,
                "status": "active"
            }
            await db.premium_memberships.insert_one(premium_membership)
            
        elif payment_type == "tip" and target_id:
            # Record tip for writer
            tip_record = {
                "id": str(uuid.uuid4()),
                "from_user_id": user_id,
                "to_writer_id": target_id,
                "amount": transaction["amount"],
                "currency": transaction["currency"],
                "message": transaction.get("metadata", {}).get("message", ""),
                "created_at": datetime.now(timezone.utc)
            }
            await db.tips.insert_one(tip_record)
            
        logger.info(f"Successfully processed {payment_type} payment for user {user_id}")
        
    except Exception as e:
        logger.error(f"Payment processing error: {str(e)}")

# User payment history and subscriptions
@api_router.get("/payments/my-transactions")
async def get_user_transactions(request: Request):
    """Get current user's payment history"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    transactions = await db.payment_transactions.find(
        {"user_id": user.id}
    ).sort("created_at", -1).limit(50).to_list(length=None)
    
    return {
        "transactions": [PaymentTransaction(**txn).dict() for txn in transactions]
    }

@api_router.get("/payments/my-subscriptions")
async def get_user_subscriptions(request: Request):
    """Get current user's active subscriptions"""
    user = await get_current_user(request, None)
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    
    subscriptions = await db.user_subscriptions.find(
        {"user_id": user.id, "status": "active"}
    ).to_list(length=None)
    
    # Enrich with writer details
    enriched_subscriptions = []
    for sub in subscriptions:
        writer = await db.users.find_one({"id": sub["writer_id"]})
        sub_data = UserSubscription(**sub).dict()
        sub_data["writer"] = UserResponse(**writer).dict() if writer else None
        enriched_subscriptions.append(sub_data)
    
    return {"subscriptions": enriched_subscriptions}

# Writer earnings and statistics
@api_router.get("/payments/writer-earnings")
async def get_writer_earnings(request: Request):
    """Get writer's earnings statistics"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    # Get subscription earnings
    subscriptions = await db.user_subscriptions.find(
        {"writer_id": user.id, "status": "active"}
    ).to_list(length=None)
    
    # Get tip earnings
    tips = await db.tips.find({"to_writer_id": user.id}).to_list(length=None)
    
    # Get chapter purchase earnings
    chapter_purchases = await db.payment_transactions.find({
        "target_id": user.id,
        "payment_type": "chapter", 
        "payment_status": "paid"
    }).to_list(length=None)
    
    total_subscriptions = len(subscriptions)
    total_tips = sum(tip["amount"] for tip in tips)
    total_chapter_sales = sum(purchase["amount"] for purchase in chapter_purchases)
    
    # Platform takes 5% cut
    platform_fee = 0.05
    net_earnings = (total_tips + total_chapter_sales) * (1 - platform_fee)
    
    return {
        "total_subscriptions": total_subscriptions,
        "total_tips": total_tips,
        "total_chapter_sales": total_chapter_sales,
        "gross_earnings": total_tips + total_chapter_sales,
        "platform_fee_percentage": platform_fee * 100,
        "net_earnings": net_earnings,
        "recent_tips": tips[-10:] if tips else [],
        "active_subscribers": total_subscriptions
    }

# Writer Withdrawal System Endpoints
@api_router.post("/payments/writer/connect-account")
async def create_writer_connect_account(request: Request):
    """Create Stripe Connect Express account for writer"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    # Check if writer already has a Connect account
    existing_account = await db.writer_stripe_accounts.find_one({"writer_id": user.id})
    if existing_account:
        # If account exists but onboarding isn't complete, return existing account info
        if not existing_account.get("onboarding_completed", False):
            # Check if this is a mock account or real Stripe account
            if existing_account["stripe_connect_account_id"].startswith("mock_"):
                return {
                    "account_id": existing_account["stripe_connect_account_id"],
                    "onboarding_url": f"{request.base_url}writer/connect/mock-success",
                    "onboarding_completed": False,
                    "mock_account": True
                }
            else:
                # Real Stripe account
                stripe.api_key = os.environ.get('STRIPE_API_KEY')
                
                try:
                    # Create account link for existing account
                    account_link = stripe.AccountLink.create(
                        account=existing_account["stripe_connect_account_id"],
                        refresh_url=f"{request.base_url}writer/connect/refresh",
                        return_url=f"{request.base_url}writer/connect/success",
                        type="account_onboarding",
                    )
                    
                    return {
                        "account_id": existing_account["stripe_connect_account_id"],
                        "onboarding_url": account_link.url,
                        "onboarding_completed": existing_account.get("onboarding_completed", False),
                        "mock_account": False
                    }
                except Exception as e:
                    logger.error(f"Error creating account link: {str(e)}")
                    # Fall back to mock if Stripe Connect is not enabled
                    return await create_mock_connect_account(user)
        else:
            raise HTTPException(status_code=409, detail="Connect account already exists and is active")
    
    try:
        # Initialize Stripe
        stripe.api_key = os.environ.get('STRIPE_API_KEY')
        
        # Try to create real Stripe Connect Express account
        account = stripe.Account.create(
            type="express",
            country="US",
            email=user.email,
            capabilities={
                "card_payments": {"requested": True},
                "transfers": {"requested": True},
            },
        )
        
        # Create account link for onboarding
        account_link = stripe.AccountLink.create(
            account=account.id,
            refresh_url=f"{request.base_url}writer/connect/refresh",
            return_url=f"{request.base_url}writer/connect/success",
            type="account_onboarding",
        )
        
        # Store Connect account info in database
        writer_account = WriterStripeAccount(
            writer_id=user.id,
            stripe_connect_account_id=account.id,
            account_status="pending",
            onboarding_completed=False,
            charges_enabled=False,
            payouts_enabled=False
        )
        
        await db.writer_stripe_accounts.insert_one(writer_account.dict())
        
        return {
            "account_id": account.id,
            "onboarding_url": account_link.url,
            "onboarding_completed": False,
            "mock_account": False
        }
        
    except Exception as e:
        logger.error(f"Error creating Connect account: {str(e)}")
        # Check if this is a Connect-not-enabled error
        error_message = str(e).lower()
        if "signed up for connect" in error_message or "connect" in error_message:
            logger.info("Stripe Connect not enabled on this account, falling back to mock system")
            return await create_mock_connect_account(user)
        else:
            raise HTTPException(status_code=500, detail="Failed to create Connect account")

async def create_mock_connect_account(user):
    """Create a mock Connect account for testing when Stripe Connect is not available"""
    mock_account_id = f"mock_acct_{user.id[:8]}_{int(datetime.now().timestamp())}"
    
    # Store mock Connect account info in database
    writer_account = WriterStripeAccount(
        writer_id=user.id,
        stripe_connect_account_id=mock_account_id,
        account_status="pending",
        onboarding_completed=False,
        charges_enabled=False,
        payouts_enabled=False
    )
    
    await db.writer_stripe_accounts.insert_one(writer_account.dict())
    
    return {
        "account_id": mock_account_id,
        "onboarding_url": f"/writer/connect/mock-success",  # Mock onboarding URL
        "onboarding_completed": False,
        "mock_account": True,
        "message": "Mock Connect account created for testing (Stripe Connect not enabled on this API key)"
    }

@api_router.get("/payments/writer/connect-status")
async def get_writer_connect_status(request: Request):
    """Get writer's Stripe Connect account status"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    writer_account = await db.writer_stripe_accounts.find_one({"writer_id": user.id})
    if not writer_account:
        return {
            "has_account": False,
            "onboarding_completed": False,
            "payouts_enabled": False,
            "account_status": "none",
            "mock_account": False
        }
    
    # Handle mock accounts
    if writer_account["stripe_connect_account_id"].startswith("mock_"):
        return {
            "has_account": True,
            "account_id": writer_account["stripe_connect_account_id"],
            "onboarding_completed": writer_account.get("onboarding_completed", False),
            "payouts_enabled": writer_account.get("payouts_enabled", False),
            "charges_enabled": writer_account.get("charges_enabled", False),
            "account_status": writer_account.get("account_status", "pending"),
            "mock_account": True,
            "requirements": None
        }
    
    try:
        # Get latest account info from Stripe
        stripe.api_key = os.environ.get('STRIPE_API_KEY')
        account = stripe.Account.retrieve(writer_account["stripe_connect_account_id"])
        
        # Update local database with latest info
        update_data = {
            "account_status": "verified" if account.details_submitted else "pending",
            "onboarding_completed": account.details_submitted,
            "charges_enabled": account.charges_enabled,
            "payouts_enabled": account.payouts_enabled,
            "requirements": dict(account.requirements) if account.requirements else None,
            "updated_at": datetime.now(timezone.utc)
        }
        
        await db.writer_stripe_accounts.update_one(
            {"writer_id": user.id},
            {"$set": update_data}
        )
        
        return {
            "has_account": True,
            "account_id": account.id,
            "onboarding_completed": account.details_submitted,
            "payouts_enabled": account.payouts_enabled,
            "charges_enabled": account.charges_enabled,
            "account_status": "verified" if account.details_submitted else "pending",
            "requirements": dict(account.requirements) if account.requirements else None,
            "mock_account": False
        }
        
    except Exception as e:
        logger.error(f"Error fetching Connect account status: {str(e)}")
        # For real accounts that fail, return cached data
        return {
            "has_account": True,
            "account_id": writer_account["stripe_connect_account_id"],
            "onboarding_completed": writer_account.get("onboarding_completed", False),
            "payouts_enabled": writer_account.get("payouts_enabled", False),
            "charges_enabled": writer_account.get("charges_enabled", False),
            "account_status": writer_account.get("account_status", "pending"),
            "mock_account": False,
            "error": "Could not fetch latest status from Stripe"
        }

@api_router.post("/payments/writer/mock-complete-onboarding")
async def mock_complete_onboarding(request: Request):
    """Mock endpoint to complete onboarding for testing purposes"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    writer_account = await db.writer_stripe_accounts.find_one({"writer_id": user.id})
    if not writer_account:
        raise HTTPException(status_code=404, detail="No Connect account found")
    
    if not writer_account["stripe_connect_account_id"].startswith("mock_"):
        raise HTTPException(status_code=400, detail="This endpoint is only for mock accounts")
    
    # Update mock account to completed status
    await db.writer_stripe_accounts.update_one(
        {"writer_id": user.id},
        {"$set": {
            "account_status": "verified",
            "onboarding_completed": True,
            "charges_enabled": True,
            "payouts_enabled": True,
            "updated_at": datetime.now(timezone.utc)
        }}
    )
    
    return {
        "message": "Mock Connect account onboarding completed",
        "account_status": "verified",
        "payouts_enabled": True
    }

@api_router.post("/payments/writer/withdrawal")
async def create_withdrawal_request(withdrawal_data: CreateWithdrawalRequest, request: Request):
    """Create withdrawal request for writer"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    # Validate withdrawal amount
    if withdrawal_data.amount < 1.00:
        raise HTTPException(status_code=400, detail="Minimum withdrawal amount is $1.00")
    
    if withdrawal_data.amount > 10000.00:
        raise HTTPException(status_code=400, detail="Maximum withdrawal amount is $10,000.00")
    
    # Check if writer has Connect account and it's verified
    writer_account = await db.writer_stripe_accounts.find_one({"writer_id": user.id})
    if not writer_account or not writer_account.get("payouts_enabled", False):
        raise HTTPException(status_code=400, detail="Stripe Connect account not verified for payouts")
    
    # Calculate writer's current available balance
    # Get earnings (tips + chapter sales - already collected fees)
    tips = await db.tips.find({"to_writer_id": user.id}).to_list(length=None)
    chapter_purchases = await db.payment_transactions.find({
        "target_id": user.id,
        "payment_type": "chapter", 
        "payment_status": "paid"
    }).to_list(length=None)
    
    # Get previous withdrawals
    previous_withdrawals = await db.withdrawal_requests.find({
        "writer_id": user.id,
        "status": {"$in": ["completed", "processing"]}
    }).to_list(length=None)
    
    total_earnings = sum(tip["amount"] for tip in tips) + sum(purchase["amount"] for purchase in chapter_purchases)
    total_withdrawn = sum(withdrawal["amount"] for withdrawal in previous_withdrawals)
    
    # Platform takes 5% fee - calculate available balance after fees
    platform_fee = 0.05
    available_balance = (total_earnings * (1 - platform_fee)) - total_withdrawn
    
    if withdrawal_data.amount > available_balance:
        raise HTTPException(
            status_code=400, 
            detail=f"Insufficient balance. Available: ${available_balance:.2f}, Requested: ${withdrawal_data.amount:.2f}"
        )
    
    try:
        # Calculate fee and net amount (Stripe's transfer fee)
        stripe_fee = 0.0025  # 0.25% Stripe transfer fee
        fee_amount = withdrawal_data.amount * stripe_fee
        net_amount = withdrawal_data.amount - fee_amount
        
        # Create withdrawal request
        withdrawal_request = WithdrawalRequest(
            writer_id=user.id,
            amount=withdrawal_data.amount,
            currency="usd",
            status="pending",
            fee_amount=fee_amount,
            net_amount=net_amount,
            notes=withdrawal_data.notes
        )
        
        await db.withdrawal_requests.insert_one(withdrawal_request.dict())
        
        # For now, we'll mark it as processing - in a real system, this would go through approval
        # Let's auto-process small amounts (under $100) and require manual approval for larger amounts
        if withdrawal_data.amount <= 100.00:
            # Auto-process small withdrawals
            try:
                stripe.api_key = os.environ.get('STRIPE_API_KEY')
                
                # Create Stripe transfer to writer's Connect account
                if writer_account["stripe_connect_account_id"].startswith("mock_"):
                    # Handle mock transfer
                    mock_transfer_id = f"tr_mock_{withdrawal_request.id[:8]}_{int(datetime.now().timestamp())}"
                    
                    # Update withdrawal request
                    await db.withdrawal_requests.update_one(
                        {"id": withdrawal_request.id},
                        {"$set": {
                            "status": "completed",
                            "processed_at": datetime.now(timezone.utc),
                            "stripe_transfer_id": mock_transfer_id
                        }}
                    )
                    
                    return {
                        "withdrawal_id": withdrawal_request.id,
                        "amount": withdrawal_data.amount,
                        "fee_amount": fee_amount,
                        "net_amount": net_amount,
                        "status": "completed",
                        "stripe_transfer_id": mock_transfer_id,
                        "message": "Mock withdrawal processed successfully (Connect testing mode)",
                        "mock_transfer": True
                    }
                else:
                    # Real Stripe transfer
                    transfer = stripe.Transfer.create(
                        amount=int(net_amount * 100),  # Stripe expects cents
                        currency="usd",
                        destination=writer_account["stripe_connect_account_id"],
                        description=f"Writer earnings withdrawal - {user.name}",
                        metadata={
                            "writer_id": user.id,
                            "withdrawal_request_id": withdrawal_request.id
                        }
                    )
                    
                    # Update withdrawal request
                    await db.withdrawal_requests.update_one(
                        {"id": withdrawal_request.id},
                        {"$set": {
                            "status": "completed",
                            "processed_at": datetime.now(timezone.utc),
                            "stripe_transfer_id": transfer.id
                        }}
                    )
                    
                    return {
                        "withdrawal_id": withdrawal_request.id,
                        "amount": withdrawal_data.amount,
                        "fee_amount": fee_amount,
                        "net_amount": net_amount,
                        "status": "completed",
                        "stripe_transfer_id": transfer.id,
                        "message": "Withdrawal processed successfully",
                        "mock_transfer": False
                    }
                
            except Exception as stripe_error:
                # Update withdrawal as failed
                await db.withdrawal_requests.update_one(
                    {"id": withdrawal_request.id},
                    {"$set": {
                        "status": "failed",
                        "failure_reason": str(stripe_error)
                    }}
                )
                
                raise HTTPException(status_code=500, detail="Failed to process withdrawal")
        else:
            # Larger amounts require manual approval (for this demo, we'll simulate approval)
            return {
                "withdrawal_id": withdrawal_request.id,
                "amount": withdrawal_data.amount,
                "fee_amount": fee_amount,
                "net_amount": net_amount,
                "status": "pending",
                "message": "Withdrawal request submitted for approval (amounts over $100 require manual review)"
            }
            
    except Exception as e:
        logger.error(f"Error creating withdrawal request: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to create withdrawal request")

@api_router.get("/payments/writer/withdrawals")
async def get_writer_withdrawals(request: Request):
    """Get writer's withdrawal history"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    withdrawals = await db.withdrawal_requests.find(
        {"writer_id": user.id}
    ).sort({"status": 1, "requested_at": -1}).limit(50).to_list(length=None)
    
    return {
        "withdrawals": [WithdrawalRequest(**withdrawal).dict() for withdrawal in withdrawals]
    }

@api_router.get("/payments/writer/balance")
async def get_writer_balance(request: Request):
    """Get writer's current available balance"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    # Calculate current earnings and available balance
    tips = await db.tips.find({"to_writer_id": user.id}).to_list(length=None)
    chapter_purchases = await db.payment_transactions.find({
        "target_id": user.id,
        "payment_type": "chapter", 
        "payment_status": "paid"
    }).to_list(length=None)
    
    # Get completed withdrawals
    completed_withdrawals = await db.withdrawal_requests.find({
        "writer_id": user.id,
        "status": "completed"
    }).to_list(length=None)
    
    # Get pending withdrawals
    pending_withdrawals = await db.withdrawal_requests.find({
        "writer_id": user.id,
        "status": {"$in": ["pending", "processing"]}
    }).to_list(length=None)
    
    total_earnings = sum(tip["amount"] for tip in tips) + sum(purchase["amount"] for purchase in chapter_purchases)
    total_withdrawn = sum(withdrawal["amount"] for withdrawal in completed_withdrawals)
    pending_amount = sum(withdrawal["amount"] for withdrawal in pending_withdrawals)
    
    # Platform fee
    platform_fee = 0.05
    gross_earnings = total_earnings
    platform_fee_amount = total_earnings * platform_fee
    net_earnings = total_earnings * (1 - platform_fee)
    
    available_balance = net_earnings - total_withdrawn - pending_amount
    
    return {
        "gross_earnings": gross_earnings,
        "platform_fee_amount": platform_fee_amount,
        "platform_fee_percentage": platform_fee * 100,
        "net_earnings": net_earnings,
        "total_withdrawn": total_withdrawn,
        "pending_withdrawals": pending_amount,
        "available_balance": available_balance,
        "minimum_withdrawal": 1.00,
        "maximum_withdrawal": 10000.00
    }

@api_router.put("/payments/writer/withdrawal-settings")
async def update_withdrawal_settings(settings_update: UpdateWithdrawalSettings, request: Request):
    """Update writer's withdrawal settings"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    # Get existing settings or create new ones
    existing_settings = await db.withdrawal_settings.find_one({"writer_id": user.id})
    
    if existing_settings:
        # Update existing settings
        update_data = {k: v for k, v in settings_update.dict().items() if v is not None}
        if update_data:
            await db.withdrawal_settings.update_one(
                {"writer_id": user.id},
                {"$set": update_data}
            )
    else:
        # Create new settings
        new_settings = WithdrawalSettings(
            writer_id=user.id,
            **{k: v for k, v in settings_update.dict().items() if v is not None}
        )
        await db.withdrawal_settings.insert_one(new_settings.dict())
    
    # Return updated settings
    updated_settings = await db.withdrawal_settings.find_one({"writer_id": user.id})
    return WithdrawalSettings(**updated_settings).dict()

@api_router.get("/payments/writer/withdrawal-settings")
async def get_withdrawal_settings(request: Request):
    """Get writer's withdrawal settings"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "writer":
        raise HTTPException(status_code=403, detail="Writer access required")
    
    settings = await db.withdrawal_settings.find_one({"writer_id": user.id})
    if not settings:
        # Return default settings
        default_settings = WithdrawalSettings(writer_id=user.id)
        return default_settings.dict()
    
    return WithdrawalSettings(**settings).dict()

# Admin endpoints for withdrawal management
@api_router.get("/admin/payments/withdrawals")
async def get_all_withdrawal_requests(request: Request):
    """Admin: Get all withdrawal requests"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "admin":
        raise HTTPException(status_code=403, detail="Admin access required")
    
    withdrawals = await db.withdrawal_requests.find({}).sort({"status": 1, "requested_at": -1}).limit(100).to_list(length=None)
    
    # Enrich with writer details
    enriched_withdrawals = []
    for withdrawal in withdrawals:
        writer = await db.users.find_one({"id": withdrawal["writer_id"]})
        withdrawal_data = WithdrawalRequest(**withdrawal).dict()
        withdrawal_data["writer"] = {"id": writer["id"], "name": writer["name"], "email": writer["email"]} if writer else None
        enriched_withdrawals.append(withdrawal_data)
    
    return {"withdrawals": enriched_withdrawals}

@api_router.put("/admin/payments/withdrawals/{withdrawal_id}/approve")
async def approve_withdrawal_request(withdrawal_id: str, request: Request):
    """Admin: Approve withdrawal request"""
    user = await get_current_user(request, None)
    if not user or user.user_type != "admin":
        raise HTTPException(status_code=403, detail="Admin access required")
    
    withdrawal = await db.withdrawal_requests.find_one({"id": withdrawal_id})
    if not withdrawal or withdrawal["status"] != "pending":
        raise HTTPException(status_code=404, detail="Pending withdrawal request not found")
    
    writer_account = await db.writer_stripe_accounts.find_one({"writer_id": withdrawal["writer_id"]})
    if not writer_account or not writer_account.get("payouts_enabled", False):
        raise HTTPException(status_code=400, detail="Writer's Stripe account not enabled for payouts")
    
    try:
        stripe.api_key = os.environ.get('STRIPE_API_KEY')
        
        # Create Stripe transfer
        transfer = stripe.Transfer.create(
            amount=int(withdrawal["net_amount"] * 100),  # Stripe expects cents
            currency="usd",
            destination=writer_account["stripe_connect_account_id"],
            description=f"Admin approved withdrawal - Writer ID: {withdrawal['writer_id']}",
            metadata={
                "withdrawal_request_id": withdrawal_id,
                "approved_by": user.id
            }
        )
        
        # Update withdrawal request
        await db.withdrawal_requests.update_one(
            {"id": withdrawal_id},
            {"$set": {
                "status": "completed",
                "processed_at": datetime.now(timezone.utc),
                "stripe_transfer_id": transfer.id
            }}
        )
        
        return {
            "message": "Withdrawal approved and processed",
            "stripe_transfer_id": transfer.id
        }
        
    except Exception as e:
        # Mark as failed
        await db.withdrawal_requests.update_one(
            {"id": withdrawal_id},
            {"$set": {
                "status": "failed",
                "failure_reason": str(e)
            }}
        )
        
        logger.error(f"Error approving withdrawal: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to process withdrawal")

@api_router.post("/email/test")
async def send_test_email(email: str):
    """Send a test email"""
    message = MessageSchema(
        subject="Test Email from Queens Mountain",
        recipients=[email],
        body="This is a test email to verify email functionality.",
        subtype="plain"
    )
    
    try:
        await fm.send_message(message)
        return {"message": "Test email sent successfully"}
    except Exception as e:
        logger.error(f"Error sending test email: {str(e)}")
        raise HTTPException(status_code=500, detail="Failed to send email")

app.include_router(api_router)

app.add_middleware(
    CORSMiddleware,
    allow_credentials=True,
    allow_origins=[
        "http://localhost:3000",  # React development server
        "https://flickerfix.preview.emergentagent.com",  # Production domain
        "https://flickerfix.preview.emergentagent.com"  # Preview environments
    ] if os.environ.get('CORS_ORIGINS', '') != '*' else ["*"],
    allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    allow_headers=["*"],
)

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

@app.on_event("shutdown")
async def shutdown_db_client():
    client.close()
