"""User frontend routes (LinkedIn OAuth protected)."""
import asyncio
import json
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Optional
from uuid import UUID

from fastapi import APIRouter, Request, Form, BackgroundTasks, HTTPException, UploadFile
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse, RedirectResponse, StreamingResponse, JSONResponse
from pydantic import BaseModel
from loguru import logger

from src.config import settings
from src.database import db
from src.orchestrator import orchestrator
from src.web.user.auth import (
    get_user_session, get_user_session_async, set_user_session, clear_user_session,
    get_supabase_login_url, handle_oauth_callback, UserSession,
    handle_email_password_login, create_email_password_user, sign_out,
    USER_SESSION_COOKIE
)
from src.web.user.password_auth import (
    hash_password, verify_password, generate_invitation_token,
    get_invitation_expiry, is_token_expired, validate_password_strength
)
from src.services.email_service import (
    send_approval_request_email,
    send_company_approval_request_email,
    send_company_review_notification_email,
    send_decision_notification_email,
    generate_token,
    validate_token,
    mark_token_used,
)
from src.services.background_jobs import (
    JobType, JobStatus,
    run_post_scraping, run_profile_analysis, run_post_categorization, run_post_type_analysis,
    run_full_analysis_pipeline, run_post_recategorization
)
from src.services.db_job_manager import job_manager
from src.services.storage_service import storage
from src.services.link_extractor import LinkExtractor, LinkExtractionError
from src.services.file_extractor import FileExtractor, FileExtractionError
from src.agents.link_topic_builder import LinkTopicBuilderAgent
from src.agents.strategy_importer import StrategyImporterAgent
from src.services.post_insights_service import compute_post_insights, refresh_post_insights_for_account
from src.services.insights_summary_service import generate_insights_summary
from src.utils.post_cleanup import sanitize_post_content

# Router for user frontend
user_router = APIRouter(tags=["user"])

# Templates
templates = Jinja2Templates(directory=Path(__file__).parent.parent / "templates" / "user")
base_templates = Jinja2Templates(directory=Path(__file__).parent.parent / "templates")

# Store for progress updates
progress_store = {}


async def get_user_profile_picture(user_id: UUID) -> Optional[str]:
    """Get profile picture URL with priority: LinkedInAccount > Profile.profile_picture.

    Priority:
    1. LinkedInAccount.linkedin_picture (if account exists and is active)
    2. Profile.profile_picture (from setup process)

    Note: session.linkedin_picture (OAuth login) should be checked by caller first.
    """
    # Prefer cached profile picture (Supabase) to avoid LinkedIn hotlink blocking
    profile = await db.get_profile(user_id)
    if profile and profile.profile_picture:
        return profile.profile_picture

    # Fall back to connected LinkedIn account
    linkedin_account = await db.get_linkedin_account(user_id)
    if linkedin_account and linkedin_account.is_active and linkedin_account.linkedin_picture:
        return linkedin_account.linkedin_picture

    return None


async def get_user_avatar(session: UserSession, user_id: UUID) -> Optional[str]:
    """Get user avatar URL with complete priority order.

    Priority:
    1. LinkedInAccount.linkedin_picture (connected LinkedIn account for auto-posting)
    2. Profile.profile_picture (from setup process)
    3. session.linkedin_picture (from OAuth login)

    Returns None if no avatar is available (caller should show initials).
    """
    # First check LinkedInAccount and Profile
    avatar = await get_user_profile_picture(user_id)
    if avatar:
        return avatar

    # Fall back to session picture (OAuth login)
    if session and session.linkedin_picture:
        return session.linkedin_picture

    return None


async def cache_linkedin_picture(
    picture_url: Optional[str],
    user_id: UUID,
    http_client: Optional["httpx.AsyncClient"] = None
) -> Optional[str]:
    """Download LinkedIn profile picture once and store in Supabase."""
    if not picture_url:
        return None

    try:
        import httpx
        close_client = False
        client = http_client
        if client is None:
            client = httpx.AsyncClient(timeout=30.0)
            close_client = True

        headers = {
            "User-Agent": "Mozilla/5.0",
            "Referer": "https://www.linkedin.com/",
            "Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
        }
        response = await client.get(picture_url, headers=headers)
        if response.status_code != 200 or not response.content:
            return picture_url

        content_type = response.headers.get("content-type", "image/jpeg")
        uploaded_url = await storage.upload_media(
            file_content=response.content,
            content_type=content_type,
            user_id=user_id
        )

        if close_client:
            await client.aclose()

        return uploaded_url or picture_url
    except Exception as e:
        logger.warning(f"Failed to cache LinkedIn picture: {e}")
        return picture_url



async def get_employee_permissions_or_default(user_id: UUID, company_id: UUID) -> dict:
    """Get employee permissions for a company, returning all-true defaults if no row exists."""
    perms = await db.get_employee_permissions(user_id, company_id)
    if perms:
        return perms.model_dump()
    return {
        "can_create_posts": True,
        "can_view_posts": True,
        "can_edit_posts": True,
        "can_schedule_posts": True,
        "can_manage_post_types": True,
        "can_do_research": True,
        "can_see_in_calendar": True,
    }


def require_user_session(request: Request) -> Optional[UserSession]:
    """Check if user is authenticated, redirect to login if not."""
    session = get_user_session(request)
    if not session:
        return None
    return session


# ==================== PUBLIC ROUTES ====================

@user_router.get("/privacy-policy", response_class=HTMLResponse)
async def privacy_policy(request: Request):
    """Public privacy policy page."""
    from datetime import date
    return base_templates.TemplateResponse("privacy_policy.html", {
        "request": request,
        "current_date": date.today().strftime("%d.%m.%Y")
    })


# ==================== AUTH ROUTES ====================

@user_router.get("/login", response_class=HTMLResponse)
async def login_page(request: Request, error: str = None):
    """User login page with LinkedIn OAuth button."""
    # If already logged in, redirect to dashboard
    session = get_user_session(request)
    if session:
        return RedirectResponse(url="/", status_code=302)

    return templates.TemplateResponse("login.html", {
        "request": request,
        "error": error
    })


@user_router.get("/auth/linkedin")
async def start_oauth(request: Request):
    """Start LinkedIn OAuth flow via Supabase."""
    # Build callback URL
    callback_url = settings.supabase_redirect_url
    if not callback_url:
        # Fallback to constructing from request
        callback_url = str(request.url_for("oauth_callback"))

    login_url = get_supabase_login_url(callback_url)
    return RedirectResponse(url=login_url, status_code=302)


@user_router.get("/auth/callback")
async def oauth_callback(
    request: Request,
    access_token: str = None,
    refresh_token: str = None,
    error: str = None,
    error_description: str = None
):
    """Handle OAuth callback from Supabase."""
    if error:
        logger.error(f"OAuth error: {error} - {error_description}")
        return RedirectResponse(url=f"/login?error={error}", status_code=302)

    # Supabase returns tokens in URL hash, not query params
    # We need to handle this client-side and redirect back
    # Check if we have the tokens
    if not access_token:
        # Render a page that extracts hash params and redirects
        return templates.TemplateResponse("auth_callback.html", {
            "request": request
        })

    # We have the tokens, try to authenticate
    session, access_tok, refresh_tok = await handle_oauth_callback(access_token, refresh_token)

    if not session:
        return RedirectResponse(url="/not-authorized", status_code=302)

    # Check onboarding status
    if not session.is_onboarding_complete:
        if session.account_type == "company":
            redirect_url = "/onboarding/company"
        else:
            redirect_url = "/onboarding/profile"
    else:
        redirect_url = "/"

    # Success - set session and redirect
    response = RedirectResponse(url=redirect_url, status_code=302)
    set_user_session(response, session, access_tok, refresh_tok)
    return response


@user_router.get("/logout")
async def logout(request: Request):
    """Log out user from Supabase Auth."""
    # Try to sign out from Supabase
    access_token = request.cookies.get(USER_SESSION_COOKIE)
    if access_token:
        await sign_out(access_token)

    response = RedirectResponse(url="/login", status_code=302)
    clear_user_session(response)
    return response


@user_router.get("/not-authorized", response_class=HTMLResponse)
async def not_authorized_page(request: Request):
    """Page shown when user's LinkedIn profile doesn't match any customer."""
    return templates.TemplateResponse("not_authorized.html", {
        "request": request
    })


# ==================== REGISTRATION ROUTES ====================

@user_router.get("/register", response_class=HTMLResponse)
async def register_page(request: Request):
    """Registration page - redirect directly to company registration.

    GHOSTWRITER FEATURE DISABLED: To re-enable, show register.html template instead.
    """
    session = get_user_session(request)
    if session and session.is_onboarding_complete:
        return RedirectResponse(url="/", status_code=302)
    # Redirect directly to company registration (ghostwriter disabled)
    return RedirectResponse(url="/register/company", status_code=302)


# ==================== GHOSTWRITER REGISTRATION (DISABLED) ====================
# To re-enable ghostwriter registration:
# 1. Uncomment these routes
# 2. Change /register route to show register.html template
# 3. Update login.html to show ghostwriter registration link

# @user_router.get("/register/ghostwriter", response_class=HTMLResponse)
# async def register_ghostwriter_page(request: Request, error: str = None):
#     """Ghostwriter registration page."""
#     session = get_user_session(request)
#     if session and session.is_onboarding_complete:
#         return RedirectResponse(url="/", status_code=302)
#     return templates.TemplateResponse("register_ghostwriter.html", {
#         "request": request,
#         "error": error
#     })


# @user_router.post("/register/ghostwriter")
# async def register_ghostwriter(
#     request: Request,
#     email: str = Form(...),
#     password: str = Form(...),
#     password_confirm: str = Form(...)
# ):
#     """Handle ghostwriter registration with email/password."""
#     if password != password_confirm:
#         return templates.TemplateResponse("register_ghostwriter.html", {
#             "request": request,
#             "error": "Passwörter stimmen nicht überein"
#         })
#
#     # Create user via Supabase Auth
#     session, access_token, refresh_token, error = await create_email_password_user(
#         email, password, "ghostwriter"
#     )
#
#     if not session:
#         return templates.TemplateResponse("register_ghostwriter.html", {
#             "request": request,
#             "error": error or "E-Mail bereits registriert oder ungültig"
#         })
#
#     # Set session and redirect to onboarding
#     response = RedirectResponse(url="/onboarding/profile", status_code=302)
#     set_user_session(response, session, access_token, refresh_token)
#     return response


@user_router.get("/register/company", response_class=HTMLResponse)
async def register_company_page(request: Request, error: str = None):
    """Company registration page."""
    session = get_user_session(request)
    if session and session.is_onboarding_complete:
        return RedirectResponse(url="/", status_code=302)
    return templates.TemplateResponse("register_company.html", {
        "request": request,
        "error": error
    })


@user_router.post("/register/company")
async def register_company(
    request: Request,
    license_key: str = Form(...),
    company_name: str = Form(...),
    email: str = Form(...),
    password: str = Form(...),
    password_confirm: str = Form(...)
):
    """Handle company registration with email/password and license key validation."""
    try:
        # 1. Password match validation
        if password != password_confirm:
            return templates.TemplateResponse("register_company.html", {
                "request": request,
                "error": "Passwörter stimmen nicht überein",
                "company_name": company_name,
                "email": email
            })

        # 2. LICENSE KEY VALIDATION (BEFORE account creation)
        license_key = license_key.strip().upper()
        license = await db.get_license_key(license_key)

        if not license:
            return templates.TemplateResponse("register_company.html", {
                "request": request,
                "error": "Ungültiger Lizenzschlüssel",
                "company_name": company_name,
                "email": email
            })

        if license.used:
            return templates.TemplateResponse("register_company.html", {
                "request": request,
                "error": "Dieser Lizenzschlüssel wurde bereits verwendet",
                "company_name": company_name,
                "email": email
            })

        # 3. Create user with company account type via Supabase Auth
        session, access_token, refresh_token, error = await create_email_password_user(
            email, password, "company"
        )

        if not session:
            return templates.TemplateResponse("register_company.html", {
                "request": request,
                "error": error or "E-Mail bereits registriert oder ungültig",
                "company_name": company_name,
                "email": email
            })

        # 4. Create the company record with license key reference
        from src.database.models import Company
        company = Company(
            name=company_name,
            owner_user_id=UUID(session.user_id),
            license_key_id=license.id
        )
        created_company = await db.create_company(company)

        # 5. Mark license key as used
        await db.mark_license_key_used(license_key, created_company.id)

        # 6. Update profile with company_id
        await db.update_profile(UUID(session.user_id), {"company_id": str(created_company.id)})

        # 7. Update session
        session.company_id = str(created_company.id)
        session.company_name = company_name

        # 8. Set session and redirect to company onboarding
        response = RedirectResponse(url="/onboarding/company", status_code=302)
        set_user_session(response, session, access_token, refresh_token)
        return response

    except Exception as e:
        logger.error(f"Error in company registration: {e}")
        return templates.TemplateResponse("register_company.html", {
            "request": request,
            "error": "Ein Fehler ist aufgetreten. Bitte versuche es erneut.",
            "company_name": company_name,
            "email": email
        })


@user_router.post("/auth/login")
async def email_password_login(
    request: Request,
    email: str = Form(...),
    password: str = Form(...)
):
    """Handle email/password login via Supabase Auth."""
    session, access_token, refresh_token = await handle_email_password_login(email, password)

    if not session:
        return templates.TemplateResponse("login.html", {
            "request": request,
            "error": "Ungültige E-Mail oder Passwort"
        })

    # Check onboarding status
    if not session.is_onboarding_complete:
        # Redirect to appropriate onboarding step
        if session.account_type == "company":
            redirect_url = "/onboarding/company"
        else:
            redirect_url = "/onboarding/profile"
        response = RedirectResponse(url=redirect_url, status_code=302)
    else:
        response = RedirectResponse(url="/", status_code=302)

    set_user_session(response, session, access_token, refresh_token)
    return response


# ==================== INVITATION ROUTES ====================

@user_router.get("/invite/{token}", response_class=HTMLResponse)
async def invite_page(request: Request, token: str):
    """Display invitation acceptance page."""
    invitation = await db.get_invitation_by_token(token)

    if not invitation:
        return templates.TemplateResponse("invite_accept.html", {
            "request": request,
            "error": "Einladung nicht gefunden",
            "expired": True
        })

    # Check if expired
    if is_token_expired(invitation.expires_at):
        return templates.TemplateResponse("invite_accept.html", {
            "request": request,
            "expired": True
        })

    # Check if already accepted
    inv_status = invitation.status.value if hasattr(invitation.status, 'value') else invitation.status
    if inv_status != "pending":
        return templates.TemplateResponse("invite_accept.html", {
            "request": request,
            "error": "Diese Einladung wurde bereits verwendet",
            "expired": True
        })

    # Get company info
    company = await db.get_company(invitation.company_id)
    inviter = await db.get_user(invitation.invited_by_user_id)

    return templates.TemplateResponse("invite_accept.html", {
        "request": request,
        "invitation": invitation,
        "company_name": company.name if company else "Unbekannt",
        "inviter_name": inviter.linkedin_name or inviter.email if inviter else "Unbekannt"
    })


@user_router.post("/invite/{token}/accept")
async def accept_invitation(
    request: Request,
    token: str,
    email: str = Form(...),
    password: str = Form(...),
    password_confirm: str = Form(...)
):
    """Accept an invitation and create employee account."""
    invitation = await db.get_invitation_by_token(token)

    if not invitation:
        return templates.TemplateResponse("invite_accept.html", {
            "request": request,
            "error": "Einladung nicht gefunden",
            "expired": True
        })

    # Validate password
    if password != password_confirm:
        company = await db.get_company(invitation.company_id)
        inviter = await db.get_user(invitation.invited_by_user_id)
        return templates.TemplateResponse("invite_accept.html", {
            "request": request,
            "invitation": invitation,
            "company_name": company.name if company else "Unbekannt",
            "inviter_name": inviter.linkedin_name or inviter.email if inviter else "Unbekannt",
            "error": "Passwörter stimmen nicht überein"
        })

    is_valid, error_msg = validate_password_strength(password)
    if not is_valid:
        company = await db.get_company(invitation.company_id)
        inviter = await db.get_user(invitation.invited_by_user_id)
        return templates.TemplateResponse("invite_accept.html", {
            "request": request,
            "invitation": invitation,
            "company_name": company.name if company else "Unbekannt",
            "inviter_name": inviter.linkedin_name or inviter.email if inviter else "Unbekannt",
            "error": error_msg
        })

    # Create employee user via Supabase Auth
    session, access_token, refresh_token, error = await create_email_password_user(
        email=invitation.email,
        password=password,
        account_type="employee",
        company_id=str(invitation.company_id)
    )

    if not session:
        return templates.TemplateResponse("invite_accept.html", {
            "request": request,
            "error": error or "Konto konnte nicht erstellt werden. E-Mail bereits vergeben?",
            "expired": True
        })

    # Mark invitation as accepted
    from datetime import datetime
    await db.update_invitation(invitation.id, {
        "status": "accepted",
        "accepted_at": datetime.utcnow(),
        "accepted_by_user_id": session.user_id
    })

    # Get company name for session
    company = await db.get_company(invitation.company_id)
    session.company_name = company.name if company else None

    # Redirect to onboarding
    response = RedirectResponse(url="/onboarding/profile", status_code=302)
    set_user_session(response, session, access_token, refresh_token)
    return response


# ==================== ONBOARDING ROUTES ====================

def get_ghostwriter_steps(current: str) -> list:
    """Get onboarding steps for ghostwriter with current step highlighted."""
    steps = [
        {"name": "Profil", "status": "pending"},
        {"name": "Posts", "status": "pending"},
        {"name": "Typen", "status": "pending"},
        {"name": "Fertig", "status": "pending"}
    ]
    step_order = ["profile", "posts", "post_types", "complete"]
    current_idx = step_order.index(current) if current in step_order else 0

    for i, step in enumerate(steps):
        if i < current_idx:
            step["status"] = "done"
        elif i == current_idx:
            step["status"] = "active"
    return steps


def get_company_steps(current: str) -> list:
    """Get onboarding steps for company with current step highlighted."""
    steps = [
        {"name": "Unternehmen", "status": "pending"},
        {"name": "Strategie", "status": "pending"},
        {"name": "Fertig", "status": "pending"}
    ]
    step_order = ["company", "strategy", "complete"]
    current_idx = step_order.index(current) if current in step_order else 0

    for i, step in enumerate(steps):
        if i < current_idx:
            step["status"] = "done"
        elif i == current_idx:
            step["status"] = "active"
    return steps


def get_employee_steps(current: str) -> list:
    """Get onboarding steps for employee with current step highlighted."""
    steps = [
        {"name": "Profil", "status": "pending"},
        {"name": "Posts", "status": "pending"},
        {"name": "Typen", "status": "pending"},
        {"name": "Fertig", "status": "pending"}
    ]
    step_order = ["profile", "posts", "post_types", "complete"]
    current_idx = step_order.index(current) if current in step_order else 0

    for i, step in enumerate(steps):
        if i < current_idx:
            step["status"] = "done"
        elif i == current_idx:
            step["status"] = "active"
    return steps


@user_router.get("/onboarding/profile", response_class=HTMLResponse)
async def onboarding_profile_page(request: Request):
    """Profile setup page for ghostwriter/employee onboarding."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Check if already completed AND has user_id (to avoid redirect loop)
    if session.is_onboarding_complete and session.user_id:
        return RedirectResponse(url="/", status_code=302)

    # Prefill data from session
    prefill = {
        "name": session.linkedin_name or "",
        "linkedin_url": f"https://linkedin.com/in/{session.linkedin_vanity_name}" if session.linkedin_vanity_name else ""
    }

    # Use employee template for employees (simpler form)
    if session.account_type == "employee":
        return templates.TemplateResponse("onboarding/profile_employee.html", {
            "request": request,
            "session": session,
            "steps": get_employee_steps("profile"),
            "prefill": prefill
        })

    # Ghostwriter template (separate customer/ghostwriter fields)
    return templates.TemplateResponse("onboarding/profile.html", {
        "request": request,
        "session": session,
        "steps": get_ghostwriter_steps("profile"),
        "prefill": prefill
    })


@user_router.post("/onboarding/profile")
async def onboarding_profile_submit(
    request: Request,
    background_tasks: BackgroundTasks,
    linkedin_url: str = Form(...),
    # Employee form fields (simpler)
    name: str = Form(None),
    email: str = Form(None),
    is_employee: str = Form(None),
    # Ghostwriter form fields
    customer_name: str = Form(None),
    ghostwriter_name: str = Form(None),
    creator_email: str = Form(""),
    customer_email: str = Form(""),
    writing_style_notes: str = Form(""),
    company_name: str = Form("")
):
    """Handle profile setup form submission."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Determine if this is an employee submission
    is_employee_flow = is_employee == "true" or session.account_type == "employee"

    # For employees: name = customer_name = ghostwriter_name, email = both emails
    if is_employee_flow:
        actual_name = name or session.linkedin_name or "Mitarbeiter"
        actual_customer_name = actual_name
        actual_ghostwriter_name = actual_name
        actual_email = email or session.email or ""
        actual_creator_email = actual_email
        actual_customer_email = actual_email
    else:
        actual_customer_name = customer_name or ""
        actual_ghostwriter_name = ghostwriter_name or ""
        actual_creator_email = creator_email
        actual_customer_email = customer_email

    try:
        # Update profile with LinkedIn info and onboarding data
        user_id = UUID(session.user_id)
        profile_updates = {
            "linkedin_url": linkedin_url,
            "display_name": actual_ghostwriter_name,
            "writing_style_notes": writing_style_notes or None,
            "creator_email": actual_creator_email or None,
            "customer_email": actual_customer_email or None,
            "onboarding_status": "profile_setup"
        }

        await db.update_profile(user_id, profile_updates)
        logger.info(f"Updated profile {user_id} with LinkedIn URL: {linkedin_url}")

        # Update session
        session.onboarding_status = "profile_setup"
        session.linkedin_name = actual_ghostwriter_name

        # Determine whether to scrape or skip
        should_scrape = True
        existing_posts = await db.get_linkedin_posts(user_id)
        if existing_posts:
            # This user already has posts (e.g. re-onboarding)
            should_scrape = False
            logger.info(f"Skipping scraping - {len(existing_posts)} posts already exist for user {user_id}")

        if should_scrape:
            job = await job_manager.create_job(JobType.POST_SCRAPING, str(user_id))
            background_tasks.add_task(run_post_scraping, user_id, linkedin_url, job.id)
            logger.info(f"Started background scraping for user {user_id}")

        response = RedirectResponse(url="/onboarding/posts", status_code=302)
        set_user_session(response, session)
        return response

    except Exception as e:
        logger.error(f"Error in profile onboarding: {e}")
        # Use appropriate template based on account type
        template_name = "onboarding/profile_employee.html" if is_employee_flow else "onboarding/profile.html"
        steps = get_employee_steps("profile") if is_employee_flow else get_ghostwriter_steps("profile")
        return templates.TemplateResponse(template_name, {
            "request": request,
            "session": session,
            "steps": steps,
            "error": str(e),
            "prefill": {
                "linkedin_url": linkedin_url,
                "name": name or actual_customer_name,
                "email": email or actual_creator_email,
                "customer_name": actual_customer_name,
                "ghostwriter_name": actual_ghostwriter_name,
                "creator_email": actual_creator_email,
                "customer_email": actual_customer_email,
                "writing_style_notes": writing_style_notes,
                "company_name": company_name
            }
        })


@user_router.get("/onboarding/posts", response_class=HTMLResponse)
async def onboarding_posts_page(request: Request):
    """Posts scraping/adding page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if not session.user_id:
        return RedirectResponse(url="/onboarding/profile", status_code=302)

    user_id = UUID(session.user_id)
    profile = await db.get_profile(user_id)
    scraped_posts = await db.get_linkedin_posts(user_id)
    # Manual posts are now stored as LinkedInPost with manual:// URL
    example_posts = [p for p in scraped_posts if p.post_url and p.post_url.startswith("manual://")]
    reference_profiles = await db.get_reference_profiles(user_id)

    total_posts = len(scraped_posts)

    # Check if scraping is in progress
    active_jobs = job_manager.get_active_jobs(session.user_id)
    scraping_in_progress = any(j.job_type == JobType.POST_SCRAPING for j in active_jobs)

    return templates.TemplateResponse("onboarding/posts.html", {
        "request": request,
        "session": session,
        "steps": get_ghostwriter_steps("posts"),
        "profile": profile,
        "scraped_posts_count": len(scraped_posts),
        "example_posts": example_posts,
        "reference_profiles": reference_profiles,
        "total_posts": total_posts,
        "scraping_in_progress": scraping_in_progress
    })


@user_router.post("/onboarding/posts")
async def onboarding_posts_submit(request: Request):
    """Move to next onboarding step after posts."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Update user status
    if session.user_id:
        await db.update_user(UUID(session.user_id), {"onboarding_status": "posts_scraped"})
        session.onboarding_status = "posts_scraped"

    response = RedirectResponse(url="/onboarding/post-types", status_code=302)
    set_user_session(response, session)
    return response


@user_router.get("/api/posts-count")
async def api_posts_count(request: Request):
    """Get current post count for onboarding polling."""
    session = require_user_session(request)
    if not session or not session.user_id:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    user_id = UUID(session.user_id)
    posts = await db.get_linkedin_posts(user_id)

    # Check if scraping is active
    active_jobs = job_manager.get_active_jobs(session.user_id)
    scraping_active = any(j.job_type == JobType.POST_SCRAPING for j in active_jobs)

    return JSONResponse({
        "count": len(posts),
        "scraping_active": scraping_active
    })


@user_router.post("/api/onboarding/add-manual-post")
async def api_add_manual_post(request: Request):
    """Add a manual example post during onboarding."""
    session = require_user_session(request)
    if not session or not session.user_id:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    try:
        data = await request.json()
        post_text = data.get("post_text", "").strip()

        if not post_text:
            return JSONResponse({"error": "Post text required"}, status_code=400)

        from uuid import uuid4
        from datetime import datetime
        from src.database.models import LinkedInPost
        manual_post = LinkedInPost(
            user_id=UUID(session.user_id),
            post_text=post_text,
            post_url=f"manual://{uuid4()}",
            post_date=datetime.now(timezone.utc),
            classification_method="manual"
        )
        saved_posts = await db.save_linkedin_posts([manual_post])
        saved = saved_posts[0] if saved_posts else manual_post

        return JSONResponse({"success": True, "id": str(saved.id)})
    except Exception as e:
        logger.error(f"Error adding manual post: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/onboarding/rescrape")
async def api_rescrape(request: Request, background_tasks: BackgroundTasks):
    """Trigger re-scraping of LinkedIn posts."""
    session = require_user_session(request)
    if not session or not session.user_id:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    try:
        user_id = UUID(session.user_id)
        profile = await db.get_profile(user_id)

        if not profile or not profile.linkedin_url:
            return JSONResponse({"error": "No LinkedIn URL found"}, status_code=400)

        # Create job and start scraping
        job = await job_manager.create_job(JobType.POST_SCRAPING, session.user_id)
        background_tasks.add_task(run_post_scraping, user_id, profile.linkedin_url, job.id)

        return JSONResponse({"success": True, "job_id": job.id})
    except Exception as e:
        logger.error(f"Error starting rescrape: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.get("/onboarding/post-types", response_class=HTMLResponse)
async def onboarding_post_types_page(request: Request):
    """Post types selection page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    return templates.TemplateResponse("onboarding/post_types.html", {
        "request": request,
        "session": session,
        "steps": get_ghostwriter_steps("post_types")
    })


@user_router.post("/onboarding/post-types")
async def onboarding_post_types_submit(
    request: Request,
    post_types_json: str = Form("{}")
):
    """Save post types and move to categorization."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    try:
        import json
        post_types_data = json.loads(post_types_json)

        if post_types_data and session.user_id:
            from src.database.models import PostType
            user_id = UUID(session.user_id)

            post_types = []
            for pt_data in post_types_data:
                post_type = PostType(
                    user_id=user_id,
                    name=pt_data.get("name", ""),
                    description=pt_data.get("description"),
                    identifying_keywords=pt_data.get("identifying_keywords", [])
                )
                post_types.append(post_type)

            if post_types:
                await db.create_post_types_bulk(post_types)
                logger.info(f"Created {len(post_types)} post types for user")

        # Update status to completed (skip categorization - done in background)
        if session.user_id:
            await db.update_user(UUID(session.user_id), {"onboarding_status": "completed"})
            session.onboarding_status = "completed"

        response = RedirectResponse(url="/onboarding/complete", status_code=302)
        set_user_session(response, session)
        return response

    except Exception as e:
        logger.error(f"Error saving post types: {e}")
        return templates.TemplateResponse("onboarding/post_types.html", {
            "request": request,
            "session": session,
            "steps": get_ghostwriter_steps("post_types"),
            "error": str(e)
        })


@user_router.get("/onboarding/categorize", response_class=HTMLResponse)
async def onboarding_categorize_page(request: Request):
    """Post categorization page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if not session.user_id:
        return RedirectResponse(url="/onboarding/profile", status_code=302)

    user_id = UUID(session.user_id)
    profile = await db.get_profile(user_id)
    all_posts = await db.get_linkedin_posts(user_id)
    post_types = await db.get_post_types(user_id)

    # Count posts per type
    type_counts = {}
    for pt in post_types:
        posts_for_type = await db.get_posts_by_type(user_id, pt.id)
        type_counts[str(pt.id)] = len(posts_for_type)

    # Get uncategorized posts
    uncategorized = await db.get_unclassified_posts(user_id)

    classified_count = len(all_posts) - len(uncategorized)
    total_posts = len(all_posts)
    progress = int((classified_count / total_posts * 100)) if total_posts > 0 else 0

    post_types_with_counts = [
        {"id": str(pt.id), "name": pt.name, "count": type_counts.get(str(pt.id), 0)}
        for pt in post_types
    ]

    return templates.TemplateResponse("onboarding/categorize.html", {
        "request": request,
        "session": session,
        "steps": get_ghostwriter_steps("categorize"),
        "profile": profile,
        "post_types": post_types_with_counts,
        "total_posts": total_posts,
        "classified_count": classified_count,
        "uncategorized_count": len(uncategorized),
        "uncategorized_posts": uncategorized[:5],
        "progress": progress,
        "classification_complete": len(uncategorized) == 0 or classified_count >= 3
    })


@user_router.post("/onboarding/categorize")
async def onboarding_categorize_submit(request: Request):
    """Complete categorization and move to final step."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Run profile analysis
    if session.user_id:
        try:
            user_id = UUID(session.user_id)
            profile = await db.get_profile(user_id)
            posts = await db.get_linkedin_posts(user_id)

            # Create profile and run analysis
            from src.database.models import LinkedInProfile, ProfileAnalysis
            linkedin_profile = LinkedInProfile(
                user_id=user_id,
                profile_data={"linkedin_url": profile.linkedin_url},
                name=profile.name
            )
            await db.save_linkedin_profile(linkedin_profile)

            # Run analysis
            profile_analysis = await orchestrator.profile_analyzer.process(
                profile=linkedin_profile,
                posts=posts,
                customer_data=profile.metadata
            )

            analysis_record = ProfileAnalysis(
                user_id=user_id,
                writing_style=profile_analysis.get("writing_style", {}),
                tone_analysis=profile_analysis.get("tone_analysis", {}),
                topic_patterns=profile_analysis.get("topic_patterns", {}),
                audience_insights=profile_analysis.get("audience_insights", {}),
                full_analysis=profile_analysis
            )
            await db.save_profile_analysis(analysis_record)
            logger.info("Profile analysis completed during onboarding")

        except Exception as e:
            logger.error(f"Profile analysis failed during onboarding: {e}")

    response = RedirectResponse(url="/onboarding/complete", status_code=302)
    set_user_session(response, session)
    return response


@user_router.get("/onboarding/complete", response_class=HTMLResponse)
async def onboarding_complete_page(request: Request, background_tasks: BackgroundTasks):
    """Onboarding completion page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Mark onboarding as complete
    if session.user_id:
        await db.update_user(UUID(session.user_id), {"onboarding_status": "completed"})
        session.onboarding_status = "completed"

    customer = None
    posts_count = 0
    post_types_count = 0
    profile_analysis = None
    analysis_started = False

    if session.user_id:
        user_id = UUID(session.user_id)
        profile = await db.get_profile(user_id)
        posts = await db.get_linkedin_posts(user_id)
        posts_count = len(posts)
        post_types = await db.get_post_types(user_id)
        post_types_count = len(post_types)
        profile_analysis = await db.get_profile_analysis(user_id)

        # Start background analysis if not already done
        if not profile_analysis:
            # Check if there's no active analysis job
            active_jobs = job_manager.get_active_jobs(session.user_id)
            if not active_jobs:
                # Start full analysis pipeline in background
                background_tasks.add_task(run_full_analysis_pipeline, user_id)
                analysis_started = True
                logger.info(f"Started background analysis pipeline for user {user_id}")

    response = templates.TemplateResponse("onboarding/complete.html", {
        "request": request,
        "session": session,
        "steps": get_ghostwriter_steps("complete"),
        "profile": profile,
        "posts_count": posts_count,
        "post_types_count": post_types_count,
        "profile_analysis": profile_analysis,
        "analysis_started": analysis_started
    })
    set_user_session(response, session)
    return response


# ==================== COMPANY ONBOARDING ROUTES ====================

@user_router.get("/onboarding/company", response_class=HTMLResponse)
async def onboarding_company_page(request: Request):
    """Company data setup page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company":
        return RedirectResponse(url="/onboarding/profile", status_code=302)

    company = None
    if session.company_id:
        company = await db.get_company(UUID(session.company_id))

    return templates.TemplateResponse("onboarding/company.html", {
        "request": request,
        "session": session,
        "steps": get_company_steps("company"),
        "company": company
    })


@user_router.post("/onboarding/company")
async def onboarding_company_submit(
    request: Request,
    name: str = Form(...),
    description: str = Form(""),
    website: str = Form(""),
    industry: str = Form("")
):
    """Save company data and proceed to strategy."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    try:
        if session.company_id:
            await db.update_company(UUID(session.company_id), {
                "name": name,
                "description": description or None,
                "website": website or None,
                "industry": industry or None
            })
            session.company_name = name

        response = RedirectResponse(url="/onboarding/strategy", status_code=302)
        set_user_session(response, session)
        return response

    except Exception as e:
        logger.error(f"Error saving company data: {e}")
        return templates.TemplateResponse("onboarding/company.html", {
            "request": request,
            "session": session,
            "steps": get_company_steps("company"),
            "error": str(e)
        })


@user_router.get("/onboarding/strategy", response_class=HTMLResponse)
async def onboarding_strategy_page(request: Request):
    """Company strategy setup page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    company = None
    strategy = {}
    if session.company_id:
        company = await db.get_company(UUID(session.company_id))
        if company:
            strategy = company.company_strategy or {}

    return templates.TemplateResponse("onboarding/strategy.html", {
        "request": request,
        "session": session,
        "steps": get_company_steps("strategy"),
        "company": company,
        "strategy": strategy
    })


@user_router.post("/onboarding/strategy")
async def onboarding_strategy_submit(request: Request):
    """Save company strategy and complete onboarding."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    form = await request.form()

    # Build strategy object
    strategy = {
        "mission": form.get("mission", ""),
        "vision": form.get("vision", ""),
        "brand_voice": form.get("brand_voice", ""),
        "tone_guidelines": form.get("tone_guidelines", ""),
        "target_audience": form.get("target_audience", ""),
        "content_pillars": [p for p in form.getlist("content_pillar") if p],
        "dos": [d for d in form.getlist("do_item") if d],
        "donts": [d for d in form.getlist("dont_item") if d]
    }

    try:
        if session.company_id:
            await db.update_company(UUID(session.company_id), {
                "company_strategy": strategy,
                "onboarding_completed": True
            })

        # Mark user onboarding as complete
        if session.user_id:
            await db.update_user(UUID(session.user_id), {"onboarding_status": "completed"})
            session.onboarding_status = "completed"

        response = RedirectResponse(url="/", status_code=302)
        set_user_session(response, session)
        return response

    except Exception as e:
        logger.error(f"Error saving company strategy: {e}")
        company = await db.get_company(UUID(session.company_id)) if session.company_id else None
        return templates.TemplateResponse("onboarding/strategy.html", {
            "request": request,
            "session": session,
            "steps": get_company_steps("strategy"),
            "company": company,
            "strategy": strategy,
            "error": str(e)
        })


# ==================== PROTECTED PAGES ====================

@user_router.get("/", response_class=HTMLResponse)
async def dashboard(request: Request):
    """User dashboard - shows only their own stats."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Check if onboarding is complete
    if not session.is_onboarding_complete:
        # Redirect to appropriate onboarding step based on account type
        if session.account_type == "company":
            # Company accounts need company onboarding
            if not session.company_id:
                return RedirectResponse(url="/onboarding/company", status_code=302)
            # Check if company onboarding is done
            if session.company_id:
                company = await db.get_company(UUID(session.company_id))
                if company and not company.onboarding_completed:
                    return RedirectResponse(url="/onboarding/strategy", status_code=302)
            return RedirectResponse(url="/onboarding/company", status_code=302)
        else:
            # Ghostwriter/Employee accounts need customer profile
            onboarding_status = session.onboarding_status
            if onboarding_status == "pending":
                return RedirectResponse(url="/onboarding/profile", status_code=302)
            elif onboarding_status == "profile_setup":
                return RedirectResponse(url="/onboarding/posts", status_code=302)
            elif onboarding_status == "posts_scraped":
                return RedirectResponse(url="/onboarding/post-types", status_code=302)
            elif onboarding_status == "categorizing":
                return RedirectResponse(url="/onboarding/post-types", status_code=302)
            else:
                return RedirectResponse(url="/onboarding/profile", status_code=302)

    # For ghostwriter/employee: Check if user_id exists
    if session.account_type != "company" and not session.user_id:
        # Reset onboarding status if it was marked complete but no customer
        if session.user_id:
            await db.update_profile(UUID(session.user_id), {"onboarding_status": "pending"})
            session.onboarding_status = "pending"
        return RedirectResponse(url="/onboarding/profile", status_code=302)

    try:
        # Company accounts have a different dashboard
        if session.account_type == "company":
            # Fetch company data with error handling for missing companies
            company = None
            employees_raw = []
            pending_invitations = []
            quota = None
            license_key = None

            if session.company_id:
                try:
                    company_id_uuid = UUID(session.company_id)
                    company, employees_raw, pending_invitations, quota, license_key = await asyncio.gather(
                        db.get_company(company_id_uuid),
                        db.get_company_employees(company_id_uuid),
                        db.get_pending_invitations(company_id_uuid),
                        db.get_company_daily_quota(company_id_uuid),
                        db.get_company_limits(company_id_uuid),
                    )
                except Exception as company_error:
                    logger.warning(f"Could not load company data for {session.company_id}: {company_error}")
                    # Continue without company data - better than crashing

            # Add avatar URLs to employees (parallel)
            def _make_emp_session(emp):
                return UserSession(
                    user_id=str(emp.id),
                    linkedin_picture=emp.linkedin_picture,
                    email=emp.email,
                    account_type=emp.account_type.value if hasattr(emp.account_type, 'value') else emp.account_type,
                    display_name=emp.display_name
                )

            emp_sessions = [_make_emp_session(emp) for emp in employees_raw]
            avatar_urls = await asyncio.gather(*[get_user_avatar(s, emp.id) for s, emp in zip(emp_sessions, employees_raw)])

            employees = [
                {
                    "id": emp.id,
                    "email": emp.email,
                    "display_name": emp.display_name or emp.linkedin_name or emp.email,
                    "onboarding_status": emp.onboarding_status,
                    "avatar_url": avatar_url
                }
                for emp, avatar_url in zip(employees_raw, avatar_urls)
            ]

            user_id = UUID(session.user_id)
            profile_picture = await get_user_avatar(session, user_id)

            return templates.TemplateResponse("company_dashboard.html", {
                "request": request,
                "page": "home",
                "session": session,
                "company": company,
                "employees": employees,
                "total_employees": len(employees),
                "pending_invitations": pending_invitations,
                "quota": quota,
                "license_key": license_key,
                "profile_picture": profile_picture
            })

        # Employee accounts have their own dashboard
        user_id = UUID(session.user_id)
        profile = await db.get_profile(user_id)
        posts = await db.get_generated_posts(user_id)
        profile_picture = await get_user_avatar(session, user_id)

        if session.account_type == "employee":
            # Count post statuses
            pending_posts = len([p for p in posts if p.status in ['draft', 'pending']])
            approved_posts = len([p for p in posts if p.status in ['approved', 'ready']])

            return templates.TemplateResponse("employee_dashboard.html", {
                "request": request,
                "page": "home",
                "session": session,
                "profile": profile,
                "posts_count": len(posts),
                "pending_posts": pending_posts,
                "approved_posts": approved_posts,
                "recent_posts": posts[:5] if posts else [],
                "profile_picture": profile_picture
            })

        # Ghostwriter accounts
        return templates.TemplateResponse("dashboard.html", {
            "request": request,
            "page": "home",
            "session": session,
            "profile": profile,
            "total_posts": len(posts),
            "profile_picture": profile_picture
        })
    except Exception as e:
        logger.error(f"Error loading dashboard: {e}")
        template = "employee_dashboard.html" if session.account_type == "employee" else "dashboard.html"
        return templates.TemplateResponse(template, {
            "request": request,
            "page": "home",
            "session": session,
            "error": str(e)
        })


_ACTIVE_STATUSES = {"draft", "approved", "ready"}
_ARCHIVE_STATUSES = {"scheduled", "published", "rejected"}


@user_router.get("/posts", response_class=HTMLResponse)
async def posts_page(request: Request):
    """View user's own posts (active Kanban only)."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    try:
        user_id = UUID(session.user_id)
        profile = await db.get_profile(user_id)
        all_posts = await db.get_generated_posts(user_id)
        active_posts = [p for p in all_posts if p.status in _ACTIVE_STATUSES]
        archived_count = sum(1 for p in all_posts if p.status in _ARCHIVE_STATUSES)
        profile_picture = await get_user_avatar(session, user_id)

        return templates.TemplateResponse("posts.html", {
            "request": request,
            "page": "posts",
            "session": session,
            "profile": profile,
            "posts": active_posts,
            "total_posts": len(active_posts),
            "archived_count": archived_count,
            "profile_picture": profile_picture
        })
    except Exception as e:
        import traceback
        logger.error(f"Error loading posts: {e}")
        logger.error(f"Traceback: {traceback.format_exc()}")
        return templates.TemplateResponse("posts.html", {
            "request": request,
            "page": "posts",
            "session": session,
            "posts": [],
            "total_posts": 0,
            "archived_count": 0,
            "error": str(e)
        })


@user_router.get("/posts/archive", response_class=HTMLResponse)
async def posts_archive_page(request: Request, page: int = 1):
    """View archived posts (published, scheduled, rejected)."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    try:
        user_id = UUID(session.user_id)
        all_posts = await db.get_generated_posts(user_id)
        archived_posts = [p for p in all_posts if p.status in _ARCHIVE_STATUSES]
        # Sort: scheduled first (upcoming), then by published_at/created_at desc
        archived_posts.sort(
            key=lambda p: (
                p.status != "scheduled",
                -(p.published_at or p.created_at or datetime.min.replace(tzinfo=timezone.utc)).timestamp()
            )
        )

        per_page = 20
        total = len(archived_posts)
        total_pages = max(1, (total + per_page - 1) // per_page)
        page = max(1, min(page, total_pages))
        start = (page - 1) * per_page
        page_posts = archived_posts[start:start + per_page]

        profile_picture = await get_user_avatar(session, user_id)

        return templates.TemplateResponse("posts_archive.html", {
            "request": request,
            "page": "posts",
            "session": session,
            "posts": page_posts,
            "total": total,
            "current_page": page,
            "total_pages": total_pages,
            "per_page": per_page,
            "profile_picture": profile_picture
        })
    except Exception as e:
        logger.error(f"Error loading posts archive: {e}")
        return templates.TemplateResponse("posts_archive.html", {
            "request": request,
            "page": "posts",
            "session": session,
            "posts": [],
            "total": 0,
            "current_page": 1,
            "total_pages": 1,
            "per_page": 20,
            "error": str(e)
        })


@user_router.get("/post-types", response_class=HTMLResponse)
async def post_types_page(request: Request):
    """Post types management page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    try:
        user_id = UUID(session.user_id)

        # Get post types
        post_types = await db.get_post_types(user_id)

        # Get all linkedin posts
        all_posts = await db.get_linkedin_posts(user_id)

        # Separate categorized and uncategorized
        uncategorized_posts = [p for p in all_posts if not p.post_type_id]
        categorized_posts = [p for p in all_posts if p.post_type_id]

        # Group categorized by type
        categorized_by_type = {}
        post_type_map = {pt.id: pt.name for pt in post_types}
        for post in categorized_posts:
            type_name = post_type_map.get(post.post_type_id, "Unbekannt")
            if type_name not in categorized_by_type:
                categorized_by_type[type_name] = []
            categorized_by_type[type_name].append(post)

        profile_picture = await get_user_avatar(session, user_id)

        return templates.TemplateResponse("post_types.html", {
            "request": request,
            "page": "post_types",
            "session": session,
            "post_types": post_types,
            "uncategorized_posts": uncategorized_posts,
            "categorized_posts": categorized_posts,
            "categorized_by_type": categorized_by_type,
            "profile_picture": profile_picture
        })
    except Exception as e:
        logger.error(f"Error loading post types page: {e}")
        profile_picture = await get_user_avatar(session, UUID(session.user_id))
        return templates.TemplateResponse("post_types.html", {
            "request": request,
            "page": "post_types",
            "session": session,
            "post_types": [],
            "uncategorized_posts": [],
            "categorized_posts": [],
            "categorized_by_type": {},
            "error": str(e),
            "profile_picture": profile_picture
        })


@user_router.post("/api/categorize-post")
async def api_categorize_post(request: Request):
    """Categorize a single post."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    try:
        data = await request.json()
        post_id = UUID(data["post_id"])
        post_type_id = UUID(data["post_type_id"])

        await db.update_linkedin_post(post_id, {"post_type_id": str(post_type_id)})

        return JSONResponse({"success": True})
    except Exception as e:
        logger.error(f"Error categorizing post: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/post-types/manual-posts")
async def api_add_manual_post_for_post_types(request: Request):
    """Add a manual post from the post types page and optionally assign a type immediately."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    try:
        data = await request.json()
        user_id = UUID(session.user_id)
        post_text = (data.get("post_text") or "").strip()
        post_type_id_raw = data.get("post_type_id")

        if len(post_text) < 20:
            return JSONResponse({"error": "Post muss mindestens 20 Zeichen lang sein"}, status_code=400)

        post_type_id = UUID(post_type_id_raw) if post_type_id_raw else None
        if post_type_id:
            post_type = await db.get_post_type(post_type_id)
            if not post_type or post_type.user_id != user_id:
                return JSONResponse({"error": "Post-Typ nicht gefunden oder kein Zugriff"}, status_code=404)

        from uuid import uuid4
        from src.database.models import LinkedInPost

        manual_post = LinkedInPost(
            user_id=user_id,
            post_text=post_text,
            post_url=f"manual://{uuid4()}",
            post_date=datetime.now(timezone.utc),
            post_type_id=post_type_id,
            classification_method="manual",
            classification_confidence=1.0,
            raw_data={"source": "manual", "manual_entry": True}
        )
        saved_posts = await db.save_linkedin_posts([manual_post])
        saved = saved_posts[0] if saved_posts else None

        return JSONResponse({
            "success": True,
            "post": {
                "id": str(saved.id) if saved and saved.id else None,
                "post_text": saved.post_text if saved else post_text,
                "post_date": saved.post_date.isoformat() if saved and saved.post_date else None,
                "post_type_id": str(saved.post_type_id) if saved and saved.post_type_id else None,
            }
        })
    except Exception as e:
        logger.error(f"Error adding manual post from post types page: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.delete("/api/post-types/posts/{post_id}")
async def api_delete_post_from_post_types_page(request: Request, post_id: str):
    """Delete a post from the main post types page."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    try:
        user_id = UUID(session.user_id)
        post = await db.get_linkedin_post(UUID(post_id))
        if not post or post.user_id != user_id:
            return JSONResponse({"error": "Post nicht gefunden oder kein Zugriff"}, status_code=404)

        await db.delete_linkedin_post(UUID(post_id))
        return JSONResponse({"success": True})
    except Exception as e:
        logger.error(f"Error deleting post from post types page: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.get("/api/job-updates")
async def job_updates_sse(request: Request):
    """Server-Sent Events endpoint for job updates (Redis pub/sub — works across workers)."""
    session = require_user_session(request)
    tracking_id = getattr(session, 'user_id', None) or getattr(session, 'company_id', None)
    if not session or not tracking_id:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    async def event_generator():
        from src.services.redis_client import get_redis
        r = await get_redis()
        pubsub = r.pubsub()
        await pubsub.subscribe(f"job_updates:{tracking_id}")
        try:
            # Send any currently active jobs as the initial state
            for job in await job_manager.get_active_jobs(tracking_id):
                data = {
                    "id": job.id,
                    "job_type": job.job_type.value,
                    "status": job.status.value,
                    "progress": job.progress,
                    "message": job.message,
                    "error": job.error,
                }
                yield f"data: {json.dumps(data)}\n\n"

            # Stream pub/sub messages, keepalive on timeout
            while True:
                try:
                    msg = await asyncio.wait_for(
                        pubsub.get_message(ignore_subscribe_messages=True), timeout=30
                    )
                    if msg and msg.get("type") == "message":
                        yield f"data: {msg['data']}\n\n"
                    else:
                        yield ": keepalive\n\n"
                except asyncio.TimeoutError:
                    yield ": keepalive\n\n"
        finally:
            await pubsub.unsubscribe(f"job_updates:{tracking_id}")
            await pubsub.aclose()

    return StreamingResponse(
        event_generator(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no",
        },
    )


@user_router.post("/api/run-post-type-analysis")
async def api_run_post_type_analysis(request: Request, background_tasks: BackgroundTasks):
    """Start post type analysis in background."""
    session = require_user_session(request)
    if not session or not session.user_id:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    try:
        user_id = UUID(session.user_id)

        # Create job
        job = await job_manager.create_job(JobType.POST_TYPE_ANALYSIS, session.user_id)

        # Run in background
        background_tasks.add_task(run_post_type_analysis, user_id, job.id)

        return JSONResponse({"success": True, "job_id": job.id})
    except Exception as e:
        logger.error(f"Error starting post type analysis: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/run-full-analysis")
async def api_run_full_analysis(request: Request, background_tasks: BackgroundTasks):
    """Start full analysis pipeline in background (profile -> categorization -> post types)."""
    session = require_user_session(request)
    if not session or not session.user_id:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    try:
        user_id = UUID(session.user_id)

        # Run full pipeline in background
        background_tasks.add_task(run_full_analysis_pipeline, user_id)

        return JSONResponse({"success": True, "message": "Analysis pipeline started"})
    except Exception as e:
        logger.error(f"Error starting full analysis: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.get("/api/jobs")
async def api_get_jobs(request: Request):
    """Get all jobs for the current user."""
    session = require_user_session(request)
    if not session or not session.user_id:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    jobs = job_manager.get_user_jobs(session.user_id)
    return JSONResponse({
        "jobs": [
            {
                "id": j.id,
                "job_type": j.job_type.value,
                "status": j.status.value,
                "progress": j.progress,
                "message": j.message,
                "error": j.error,
                "created_at": j.created_at.isoformat() if j.created_at else None
            }
            for j in jobs
        ]
    })


@user_router.get("/posts/{post_id}", response_class=HTMLResponse)
async def post_detail_page(request: Request, post_id: str):
    """Detailed view of a single post."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            return RedirectResponse(url="/posts", status_code=302)

        # Verify user owns this post
        if str(post.user_id) != session.user_id:
            return RedirectResponse(url="/posts", status_code=302)

        profile, linkedin_posts, profile_picture_url, profile_analysis_record = await asyncio.gather(
            db.get_profile(post.user_id),
            db.get_linkedin_posts(post.user_id),
            get_user_avatar(session, post.user_id),
            db.get_profile_analysis(post.user_id),
        )
        reference_posts = [p.post_text for p in linkedin_posts if p.post_text and len(p.post_text) > 100][:10]
        profile_analysis = profile_analysis_record.full_analysis if profile_analysis_record else None
        style_card = None
        if profile_analysis and isinstance(profile_analysis, dict):
            from src.agents.writer import WriterAgent
            style_card = WriterAgent()._build_style_card(profile_analysis)

        post_type = None
        post_type_analysis = None
        if post.post_type_id:
            post_type = await db.get_post_type(post.post_type_id)
            if post_type and post_type.analysis:
                post_type_analysis = post_type.analysis

        final_feedback = None
        if post.critic_feedback and len(post.critic_feedback) > 0:
            final_feedback = post.critic_feedback[-1]

        # Convert media_items to dicts for JSON serialization in template
        media_items_dict = []
        if post.media_items:
            media_items_dict = [
                item.model_dump(mode='json') if hasattr(item, 'model_dump') else (item.dict() if hasattr(item, 'dict') else item)
                for item in post.media_items
            ]

        # Check token limit for quick action buttons
        limit_reached = False
        limit_message = ""
        if session.account_type in ("company", "employee") and session.company_id:
            can_proceed, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
            limit_reached = not can_proceed
            limit_message = error_msg

        return templates.TemplateResponse("post_detail.html", {
            "request": request,
            "page": "posts",
            "session": session,
            "post": post,
            "profile": profile,
            "reference_posts": reference_posts,
            "profile_analysis": profile_analysis,
            "post_type": post_type,
            "post_type_analysis": post_type_analysis,
            "final_feedback": final_feedback,
            "style_card": style_card,
            "profile_picture_url": profile_picture_url,
            "profile_picture": profile_picture_url,
            "media_items_dict": media_items_dict,
            "limit_reached": limit_reached,
            "limit_message": limit_message
        })
    except Exception as e:
        import traceback
        logger.error(f"Error loading post detail: {e}")
        logger.error(f"Traceback: {traceback.format_exc()}")
        return RedirectResponse(url="/posts", status_code=302)


@user_router.get("/research", response_class=HTMLResponse)
async def research_page(request: Request):
    """Research topics page - with limit check for companies."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Check token limit for companies/employees
    limit_reached = False
    limit_message = ""
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("research.html", {
        "request": request,
        "page": "research",
        "session": session,
        "user_id": session.user_id,
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "profile_picture": profile_picture
    })


@user_router.get("/create", response_class=HTMLResponse)
async def create_post_select_page(request: Request):
    """Post creation selection page - choose wizard or chat."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Check token limit for companies/employees
    limit_reached = False
    limit_message = ""
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("create_post_select.html", {
        "request": request,
        "page": "create",
        "session": session,
        "user_id": session.user_id,
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "profile_picture": profile_picture
    })


@user_router.get("/create/wizard", response_class=HTMLResponse)
async def create_post_page(request: Request):
    """Create post wizard page - with limit check for companies."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Check token limit for companies/employees
    limit_reached = False
    limit_message = ""
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("create_post.html", {
        "request": request,
        "page": "create",
        "session": session,
        "user_id": session.user_id,
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "profile_picture": profile_picture
    })


@user_router.get("/create/link-wizard", response_class=HTMLResponse)
async def create_post_link_page(request: Request):
    """Create post from link wizard page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Check token limit for companies/employees
    limit_reached = False
    limit_message = ""
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("create_post_link.html", {
        "request": request,
        "page": "create",
        "session": session,
        "user_id": session.user_id,
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "profile_picture": profile_picture
    })


@user_router.get("/create/file-wizard", response_class=HTMLResponse)
async def create_post_file_page(request: Request):
    """Create post from file wizard page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Check token limit for companies/employees
    limit_reached = False
    limit_message = ""
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("create_post_file.html", {
        "request": request,
        "page": "create",
        "session": session,
        "user_id": session.user_id,
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "profile_picture": profile_picture
    })


@user_router.get("/chat-create", response_class=HTMLResponse)
async def chat_create_page(request: Request):
    """Chat-based post creation page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    user_id = UUID(session.user_id)

    # Check token limit for companies/employees
    limit_reached = False
    limit_message = ""
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    # Get post types
    post_types = await db.get_post_types(user_id)
    if not post_types:
        return templates.TemplateResponse("error.html", {
            "request": request,
            "session": session,
            "error": "Keine Post-Typen gefunden. Bitte erstelle zuerst Post-Typen."
        })

    profile_picture = await get_user_avatar(session, user_id)

    # Load all saved posts for sidebar (exclude scheduled and published)
    all_posts = await db.get_generated_posts(user_id)
    saved_posts = [post for post in all_posts if post.status not in ['scheduled', 'published']]

    return templates.TemplateResponse("chat_create.html", {
        "request": request,
        "page": "chat-create",
        "session": session,
        "post_types": post_types,
        "profile_picture": profile_picture,
        "saved_posts": saved_posts,
        "limit_reached": limit_reached,
        "limit_message": limit_message
    })


# ==================== API ENDPOINTS ====================

@user_router.get("/api/post-types")
async def get_post_types(request: Request, user_id: str = None):
    """Get post types for the logged-in user or specified user (for company owners)."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        # Company owners can specify a user_id for their employees
        target_user_id = user_id if user_id and session.account_type == "company" else session.user_id
        if not target_user_id:
            return {"post_types": []}

        post_types = await db.get_post_types(UUID(target_user_id))
        return {
            "post_types": [
                {
                    "id": str(pt.id),
                    "name": pt.name,
                    "description": pt.description,
                    "has_analysis": pt.analysis is not None,
                    "analyzed_post_count": pt.analyzed_post_count,
                }
                for pt in post_types
            ]
        }
    except Exception as e:
        logger.error(f"Error loading post types: {e}")
        return {"post_types": [], "error": str(e)}


@user_router.get("/api/topics")
async def get_topics(request: Request, post_type_id: str = None, user_id: str = None):
    """Get research topics for the logged-in user or specified user (for company owners)."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        # Company owners can specify a user_id for their employees
        target_user_id = user_id if user_id and session.account_type == "company" else session.user_id
        if not target_user_id:
            return {"topics": [], "available_count": 0, "used_count": 0}

        user_id = UUID(target_user_id)
        if post_type_id:
            all_research = await db.get_all_research(user_id, UUID(post_type_id))
        else:
            all_research = await db.get_all_research(user_id)

        # Get used topics
        generated_posts = await db.get_generated_posts(user_id)
        used_topic_titles = set()
        for post in generated_posts:
            if post.topic_title:
                used_topic_titles.add(post.topic_title.lower().strip())

        all_topics = []
        for research in all_research:
            if research.suggested_topics:
                for topic in research.suggested_topics:
                    topic_title = topic.get("title", "").lower().strip()
                    if topic_title in used_topic_titles:
                        continue
                    topic["research_id"] = str(research.id)
                    topic["target_post_type_id"] = str(research.target_post_type_id) if research.target_post_type_id else None
                    all_topics.append(topic)

        return {"topics": all_topics, "used_count": len(used_topic_titles), "available_count": len(all_topics)}
    except Exception as e:
        logger.error(f"Error loading topics: {e}")
        return {"topics": [], "error": str(e)}


@user_router.get("/api/tasks/{task_id}")
async def get_task_status(task_id: str):
    """Get task progress."""
    return progress_store.get(task_id, {"status": "unknown", "message": "Task not found"})


@user_router.post("/api/research")
async def start_research(request: Request, background_tasks: BackgroundTasks, post_type_id: str = Form(None), user_id: str = Form(None)):
    """Start research for the logged-in user or specified user (for company owners)."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    # CHECK COMPANY TOKEN LIMIT
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        if not can_create:
            raise HTTPException(status_code=429, detail=error_msg)

    # Company owners can specify a user_id for their employees
    target_user_id = user_id if user_id and session.account_type == "company" else session.user_id
    if not target_user_id:
        raise HTTPException(status_code=400, detail="No user ID available")

    user_id = target_user_id
    task_id = f"research_{user_id}_{asyncio.get_event_loop().time()}"
    progress_store[task_id] = {"status": "starting", "message": "Starte Recherche...", "progress": 0}

    async def run_research():
        try:
            def progress_callback(message: str, step: int, total: int):
                progress_store[task_id] = {"status": "running", "message": message, "progress": int((step / total) * 100)}

            topics = await orchestrator.research_new_topics(
                UUID(user_id),
                progress_callback=progress_callback,
                post_type_id=UUID(post_type_id) if post_type_id else None
            )

            progress_store[task_id] = {"status": "completed", "message": f"{len(topics)} Topics gefunden!", "progress": 100, "topics": topics}
        except Exception as e:
            logger.exception(f"Research failed: {e}")
            progress_store[task_id] = {"status": "error", "message": str(e), "progress": 0}

    background_tasks.add_task(run_research)
    return {"task_id": task_id}


@user_router.post("/api/transcribe")
async def transcribe_audio(request: Request):
    """Transcribe audio using OpenAI Whisper."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    import openai
    import tempfile
    import os

    try:
        client = openai.OpenAI(api_key=settings.openai_api_key)

        # Get the uploaded file from the request
        form = await request.form()
        audio_file = form.get("audio")

        if not audio_file:
            raise HTTPException(status_code=400, detail="No audio file provided")

        # Read the audio content
        audio_content = await audio_file.read()

        # Save to temporary file (Whisper needs a file)
        with tempfile.NamedTemporaryFile(suffix=".webm", delete=False) as tmp_file:
            tmp_file.write(audio_content)
            tmp_path = tmp_file.name

        try:
            # Transcribe with Whisper
            with open(tmp_path, "rb") as f:
                transcript = client.audio.transcriptions.create(
                    model="whisper-1",
                    file=f,
                    language="de",
                    response_format="text"
                )

            return {"text": transcript}
        finally:
            # Clean up temp file
            os.unlink(tmp_path)

    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Transcription failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/link-extract")
async def extract_link(request: Request):
    """Extract context from a link and build a structured topic."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    # Check token limit for companies/employees
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        if not can_create:
            raise HTTPException(status_code=429, detail=error_msg)

    try:
        data = await request.json()
        url = (data.get("url") or "").strip()
        transcript = (data.get("transcript") or "").strip()
        manual_title = (data.get("title") or "").strip()
        source_type = (data.get("source_type") or "").strip()
        source_url = (data.get("source_url") or "").strip()

        if transcript:
            source = {
                "source_url": source_url or url,
                "source_type": source_type or "manual",
                "title": manual_title or "Manuelles Transkript",
                "text": transcript
            }
        else:
            extractor = LinkExtractor()
            try:
                source = await extractor.extract(url)
            except LinkExtractionError as exc:
                raise HTTPException(status_code=400, detail=str(exc)) from exc

        builder = LinkTopicBuilderAgent()
        builder.set_tracking_context(
            operation="link_extract",
            user_id=session.user_id,
            company_id=session.company_id
        )
        topic = await builder.process(source)

        return {"topic": topic, "source": source}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Link extraction failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/file-extract")
async def extract_file(request: Request):
    """Extract context from an uploaded file and build a structured topic."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    # Check token limit for companies/employees
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        if not can_create:
            raise HTTPException(status_code=429, detail=error_msg)

    try:
        form = await request.form()
        upload: UploadFile = form.get("file")  # type: ignore[assignment]
        if not upload:
            raise HTTPException(status_code=400, detail="Keine Datei hochgeladen.")

        # Basic validation
        allowed_ext = {".pdf", ".docx", ".pptx", ".xlsx", ".txt", ".md", ".rtf"}
        filename = upload.filename or ""
        ext = Path(filename).suffix.lower()
        if not ext or ext not in allowed_ext:
            raise HTTPException(status_code=400, detail="Dateityp nicht unterstützt.")

        file_bytes = await upload.read()
        max_bytes = 10 * 1024 * 1024  # 10 MB
        if len(file_bytes) > max_bytes:
            raise HTTPException(status_code=400, detail="Datei ist zu groß (max 10 MB).")

        extractor = FileExtractor()
        try:
            text = extractor.extract_text(file_bytes, filename)
        except FileExtractionError as exc:
            raise HTTPException(status_code=400, detail=str(exc)) from exc

        source = {
            "source_url": "",
            "source_type": "file",
            "title": filename or "Datei",
            "text": text
        }

        builder = LinkTopicBuilderAgent()
        builder.set_tracking_context(
            operation="file_extract",
            user_id=session.user_id,
            company_id=session.company_id
        )
        topic = await builder.process(source)

        return {"topic": topic, "source": source}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"File extraction failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/hooks")
async def generate_hooks(
    request: Request,
    topic_json: str = Form(...),
    user_thoughts: str = Form(""),
    post_type_id: str = Form(None),
    user_id: str = Form(None)
):
    """Generate hook options for a topic."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        topic = json.loads(topic_json)
        # Company owners can specify a user_id for their employees
        target_user_id = user_id if user_id and session.account_type == "company" else session.user_id
        if not target_user_id:
            raise HTTPException(status_code=400, detail="No user ID available")

        user_id = UUID(target_user_id)

        hooks = await orchestrator.generate_hooks(
            user_id=user_id,
            topic=topic,
            user_thoughts=user_thoughts,
            post_type_id=UUID(post_type_id) if post_type_id else None
        )

        return {"hooks": hooks}
    except Exception as e:
        logger.exception(f"Hook generation failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/posts")
async def create_post(
    request: Request,
    background_tasks: BackgroundTasks,
    topic_json: str = Form(...),
    post_type_id: str = Form(None),
    user_thoughts: str = Form(""),
    selected_hook: str = Form(""),
    user_id: str = Form(None)
):
    """Create a new post for the logged-in user or specified user (for company owners)."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    # CHECK COMPANY TOKEN LIMIT
    if session.account_type in ("company", "employee") and session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        if not can_create:
            raise HTTPException(status_code=429, detail=error_msg)

    # Company owners can specify a user_id for their employees
    target_user_id = user_id if user_id and session.account_type == "company" else session.user_id
    if not target_user_id:
        raise HTTPException(status_code=400, detail="No user ID available")

    user_id = target_user_id
    task_id = f"post_{user_id}_{asyncio.get_event_loop().time()}"
    progress_store[task_id] = {"status": "starting", "message": "Starte Post-Erstellung...", "progress": 0}
    topic = json.loads(topic_json)

    async def run_create_post():
        try:
            def progress_callback(message: str, iteration: int, max_iterations: int, score: int = None, versions: list = None, feedback_list: list = None):
                progress = int((iteration / max_iterations) * 100) if iteration > 0 else 5
                progress_store[task_id] = {
                    "status": "running", "message": message, "progress": progress,
                    "iteration": iteration, "max_iterations": max_iterations,
                    "versions": versions or [], "feedback_list": feedback_list or []
                }

            result = await orchestrator.create_post(
                user_id=UUID(user_id), topic=topic, max_iterations=2,
                progress_callback=progress_callback,
                post_type_id=UUID(post_type_id) if post_type_id else None,
                user_thoughts=user_thoughts,
                selected_hook=selected_hook
            )

            progress_store[task_id] = {
                "status": "completed", "message": "Post erstellt!", "progress": 100,
                "result": {
                    "post_id": str(result["post_id"]), "final_post": result["final_post"],
                    "iterations": result["iterations"], "final_score": result["final_score"], "approved": result["approved"]
                }
            }
        except Exception as e:
            logger.exception(f"Post creation failed: {e}")
            progress_store[task_id] = {"status": "error", "message": str(e), "progress": 0}

    background_tasks.add_task(run_create_post)
    return {"task_id": task_id}


@user_router.get("/api/posts/{post_id}/suggestions")
async def get_post_suggestions(request: Request, post_id: str):
    """Get AI improvement suggestions for a post based on critic feedback."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    # Check token limit for companies/employees
    if session.account_type in ("company", "employee") and session.company_id:
        can_proceed, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        if not can_proceed:
            raise HTTPException(status_code=429, detail=error_msg)

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Verify authorization: post owner or company with can_edit_posts
        is_owner = str(post.user_id) == session.user_id
        is_authorized = is_owner
        if not is_owner and session.account_type == "company" and session.company_id:
            profile_check = await db.get_profile(post.user_id)
            if profile_check and profile_check.company_id and str(profile_check.company_id) == session.company_id:
                edit_perms = await get_employee_permissions_or_default(post.user_id, UUID(session.company_id))
                if edit_perms.get("can_edit_posts", True):
                    is_authorized = True
        if not is_authorized:
            raise HTTPException(status_code=403, detail="Not authorized")

        # Get the last critic feedback if available
        critic_feedback = None
        if post.critic_feedback and len(post.critic_feedback) > 0:
            critic_feedback = post.critic_feedback[-1]

        suggestions = await orchestrator.generate_improvement_suggestions(
            user_id=UUID(session.user_id),
            post_content=post.post_content,
            critic_feedback=critic_feedback
        )

        return {"suggestions": suggestions}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to generate suggestions: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/posts/{post_id}/revise")
async def revise_post(
    request: Request,
    post_id: str,
    suggestion: str = Form(...)
):
    """Apply a suggestion to a post and save as new version."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    # Check token limit for companies/employees
    if session.account_type in ("company", "employee") and session.company_id:
        can_proceed, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        if not can_proceed:
            raise HTTPException(status_code=429, detail=error_msg)

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Verify authorization: post owner or company with can_edit_posts
        is_owner = str(post.user_id) == session.user_id
        is_authorized = is_owner
        if not is_owner and session.account_type == "company" and session.company_id:
            profile_check = await db.get_profile(post.user_id)
            if profile_check and profile_check.company_id and str(profile_check.company_id) == session.company_id:
                edit_perms = await get_employee_permissions_or_default(post.user_id, UUID(session.company_id))
                if edit_perms.get("can_edit_posts", True):
                    is_authorized = True
        if not is_authorized:
            raise HTTPException(status_code=403, detail="Not authorized")

        # Apply the suggestion
        improved_content = await orchestrator.apply_suggestion_to_post(
            user_id=UUID(session.user_id),
            post_content=post.post_content,
            suggestion=suggestion
        )

        # Save as new version without score
        writer_versions = post.writer_versions or []
        writer_versions.append(improved_content)

        # Update post with new content and version
        updated_post = await db.update_generated_post(
            UUID(post_id),
            {
                "post_content": improved_content,
                "writer_versions": writer_versions
            }
        )

        return {
            "success": True,
            "new_content": improved_content,
            "version_count": len(writer_versions)
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to revise post: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.patch("/api/posts/{post_id}/status")
async def update_post_status(
    request: Request,
    post_id: str,
    status: str = Form(...)
):
    """Update post status (for Kanban board). Sends email when moving to 'approved'."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    # Validate status
    valid_statuses = ["draft", "approved", "ready", "scheduled", "published"]
    if status not in valid_statuses:
        raise HTTPException(status_code=400, detail=f"Invalid status. Must be one of: {valid_statuses}")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Verify user owns this post or is a company owner of the employee
        is_owner = session.user_id and str(post.user_id) == session.user_id
        is_company_owner = False

        if not is_owner and session.account_type == "company" and session.company_id:
            # Check if this post belongs to an employee of this company
            profile = await db.get_profile(post.user_id)
            if profile and profile.company_id and str(profile.company_id) == session.company_id:
                is_company_owner = True

        if not is_owner and not is_company_owner:
            raise HTTPException(status_code=403, detail="Not authorized")

        # Company cannot set status to "ready" — only the employee/owner can
        if status == "ready" and is_company_owner:
            raise HTTPException(status_code=403, detail="Nur Mitarbeiter können Posts freigeben")

        # Get profile for email settings
        profile = await db.get_profile(post.user_id)

        # Update status
        await db.update_generated_post(UUID(post_id), {"status": status})

        base_url = str(request.base_url).rstrip('/')
        email_sent = False

        if status == "approved":
            if is_company_owner:
                # Company moved post to "approved": send approval request to employee (creator_email)
                company = await db.get_company(UUID(session.company_id))
                company_name = company.name if company else (session.company_name or "Ihr Unternehmen")

                # Generate tokens once — shared by email and Telegram buttons
                approve_token = await generate_token(UUID(post_id), "approve")
                reject_token = await generate_token(UUID(post_id), "reject")
                approve_url = f"{base_url}/api/email-action/{approve_token}"
                reject_url = f"{base_url}/api/email-action/{reject_token}"

                if profile and profile.creator_email:
                    email_sent = send_company_approval_request_email(
                        to_email=profile.creator_email,
                        post_title=post.topic_title or "Untitled Post",
                        post_content=post.post_content or "",
                        company_name=company_name,
                        approve_url=approve_url,
                        reject_url=reject_url,
                        image_url=post.image_url
                    )
                # Send Telegram notification with inline approve/reject buttons
                if settings.telegram_enabled:
                    try:
                        from src.services.telegram_service import telegram_service as _tg
                        telegram_account = await db.get_telegram_account(post.user_id)
                        if _tg and telegram_account and telegram_account.is_active:
                            await _tg.send_message(
                                chat_id=telegram_account.telegram_chat_id,
                                text=(
                                    f"📋 <b>{company_name}</b> hat deinen Post bearbeitet und bittet um deine Freigabe:\n\n"
                                    f"<i>{post.topic_title or 'Untitled Post'}</i>"
                                ),
                                reply_markup={
                                    "inline_keyboard": [[
                                        {"text": "✅ Freigeben", "callback_data": f"approve:{approve_token}"},
                                        {"text": "❌ Ablehnen", "callback_data": f"reject:{reject_token}"}
                                    ]]
                                }
                            )
                    except Exception as tg_err:
                        logger.warning(f"Telegram notification failed: {tg_err}")
                # Send Teams Adaptive Card with approve/reject buttons
                if settings.teams_enabled:
                    try:
                        from src.services.teams_service import teams_service as _ts
                        teams_account = await db.get_teams_account(post.user_id)
                        if _ts and teams_account and teams_account.is_active:
                            await _ts.send_approval_card(
                                teams_account=teams_account,
                                post_title=post.topic_title or "Untitled Post",
                                post_content=post.post_content or "",
                                approve_token=approve_token,
                                reject_token=reject_token,
                                company_name=company_name,
                            )
                    except Exception as teams_err:
                        logger.warning(f"Teams notification failed: {teams_err}")
            else:
                # Employee/owner moving their own post to "approved": no email/telegram notification
                pass

        return {"success": True, "status": status, "email_sent": email_sent}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to update post status: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.put("/api/posts/{post_id}")
async def update_post(
    request: Request,
    post_id: str,
    content: str = Form(...)
):
    """Manually update post content and save as new version."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Verify user owns this post OR is a company owner with edit permission
        is_owner = str(post.user_id) == session.user_id
        is_authorized = is_owner
        if not is_owner and session.account_type == "company" and session.company_id:
            profile_check = await db.get_profile(post.user_id)
            if profile_check and profile_check.company_id and str(profile_check.company_id) == session.company_id:
                edit_perms = await get_employee_permissions_or_default(post.user_id, UUID(session.company_id))
                if edit_perms.get("can_edit_posts", True):
                    is_authorized = True
        if not is_authorized:
            raise HTTPException(status_code=403, detail="Not authorized")

        if len(content) > 3000:
            raise HTTPException(status_code=422, detail="Post überschreitet 3000-Zeichen-Limit")

        # Save as new version
        writer_versions = post.writer_versions or []
        writer_versions.append(content)

        # Update post with new content and version
        updated_post = await db.update_generated_post(
            UUID(post_id),
            {
                "post_content": content,
                "writer_versions": writer_versions
            }
        )

        return {
            "success": True,
            "new_content": content,
            "version_count": len(writer_versions)
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to update post: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== EMAIL ACTION ENDPOINTS ====================

@user_router.get("/api/email-action/{token}", response_class=HTMLResponse)
async def handle_email_action(request: Request, token: str):
    """Handle email action (approve/reject) from email link."""
    token_data = await validate_token(token)

    if not token_data:
        return templates.TemplateResponse("email_action_result.html", {
            "request": request,
            "success": False,
            "message": "Dieser Link ist ungültig oder abgelaufen.",
            "title": "Link ungültig"
        })

    post_id = UUID(token_data["post_id"])
    action = token_data["action"]

    try:
        post = await db.get_generated_post(post_id)
        if not post:
            return templates.TemplateResponse("email_action_result.html", {
                "request": request,
                "success": False,
                "message": "Der Post wurde nicht gefunden.",
                "title": "Post nicht gefunden"
            })

        profile = await db.get_profile(post.user_id)

        # Determine new status based on action
        if action == "approve":
            new_status = "ready"
            decision = "approved"
            message = "Der Post wurde freigegeben und kann nun im Kalender eingeplant werden."
            title = "Post freigegeben"
        else:  # reject
            new_status = "draft"
            decision = "rejected"
            message = "Der Post wurde zur Überarbeitung zurückgeschickt."
            title = "Zurück zur Überarbeitung"

        # Update post status
        await db.update_generated_post(post_id, {"status": new_status})

        # Invalidate ALL tokens for this post (both approve + reject)
        await db.mark_all_post_tokens_used(post_id)

        # Send notification to creator
        if profile and profile.creator_email:
            base_url = str(request.base_url).rstrip('/')
            send_decision_notification_email(
                to_email=profile.creator_email,
                post_title=post.topic_title or "Untitled Post",
                decision=decision,
                base_url=base_url,
                post_id=post_id,
                image_url=post.image_url
            )

        return templates.TemplateResponse("email_action_result.html", {
            "request": request,
            "success": True,
            "message": message,
            "title": title,
            "action": action
        })

    except Exception as e:
        logger.exception(f"Failed to process email action: {e}")
        return templates.TemplateResponse("email_action_result.html", {
            "request": request,
            "success": False,
            "message": "Ein Fehler ist aufgetreten. Bitte versuche es später erneut.",
            "title": "Fehler"
        })


# ==================== SETTINGS ENDPOINTS ====================

@user_router.get("/settings", response_class=HTMLResponse)
async def settings_page(request: Request):
    """User settings page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    try:
        user_id = UUID(session.user_id)
        profile = await db.get_profile(user_id)
        profile_picture = await get_user_avatar(session, user_id)

        # Get LinkedIn account if linked
        linkedin_account = await db.get_linkedin_account(user_id)

        # Get Telegram account if feature is enabled
        telegram_account = None
        if settings.telegram_enabled:
            telegram_account = await db.get_telegram_account(user_id)

        # Get Teams account if feature is enabled
        teams_account = None
        if settings.teams_enabled:
            teams_account = await db.get_teams_account(user_id)

        # Get company permissions if user is an employee with a company
        company_permissions = None
        company = None
        if session.account_type == "employee" and session.company_id:
            company_permissions = await get_employee_permissions_or_default(user_id, UUID(session.company_id))
            company = await db.get_company(UUID(session.company_id))

        return templates.TemplateResponse("settings.html", {
            "request": request,
            "page": "settings",
            "session": session,
            "profile": profile,
            "profile_picture": profile_picture,
            "linkedin_account": linkedin_account,
            "telegram_enabled": settings.telegram_enabled,
            "telegram_account": telegram_account,
            "teams_enabled": settings.teams_enabled,
            "teams_account": teams_account,
            "microsoft_app_id": settings.microsoft_app_id,
            "company_permissions": company_permissions,
            "company": company,
        })
    except Exception as e:
        logger.error(f"Error loading settings: {e}")
        return templates.TemplateResponse("settings.html", {
            "request": request,
            "page": "settings",
            "session": session,
            "error": str(e)
        })


@user_router.post("/api/settings/emails")
async def update_email_settings(
    request: Request,
    creator_email: str = Form(""),
    customer_email: str = Form("")
):
    """Update email settings for the customer."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        # Update profile with new email settings
        await db.update_profile(
            UUID(session.user_id),
            {
                "creator_email": creator_email if creator_email else None,
                "customer_email": customer_email if customer_email else None
            }
        )

        return {"success": True}
    except Exception as e:
        logger.exception(f"Failed to update email settings: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/settings/company-permissions")
async def update_company_permissions(request: Request):
    """Update employee-company permissions. Checkboxes present = True, absent = False."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if session.account_type != "employee" or not session.company_id:
        raise HTTPException(status_code=403, detail="Only employees can update company permissions")

    try:
        form = await request.form()
        updates = {
            "can_create_posts": "can_create_posts" in form,
            "can_view_posts": "can_view_posts" in form,
            "can_edit_posts": "can_edit_posts" in form,
            "can_schedule_posts": "can_schedule_posts" in form,
            "can_manage_post_types": "can_manage_post_types" in form,
            "can_do_research": "can_do_research" in form,
            "can_see_in_calendar": "can_see_in_calendar" in form,
        }
        await db.upsert_employee_permissions(
            UUID(session.user_id),
            UUID(session.company_id),
            updates
        )
        return {"success": True}
    except Exception as e:
        logger.exception(f"Failed to update company permissions: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== LINKEDIN ACCOUNT LINKING ====================

@user_router.get("/settings/linkedin/connect")
async def linkedin_connect(request: Request):
    """Initiate LinkedIn OAuth for account linking."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Only employees can link LinkedIn accounts
    if session.account_type not in ["employee", "ghostwriter"]:
        return RedirectResponse(url="/settings", status_code=302)

    # Generate CSRF state token
    import secrets
    state = secrets.token_urlsafe(32)

    # Build LinkedIn OAuth URL
    from urllib.parse import urlencode
    params = {
        "response_type": "code",
        "client_id": settings.linkedin_client_id,
        "redirect_uri": settings.linkedin_redirect_uri,
        "state": state,
        "scope": "openid profile email w_member_social"
    }
    oauth_url = f"https://www.linkedin.com/oauth/v2/authorization?{urlencode(params)}"

    # Store state in cookie for verification
    response = RedirectResponse(url=oauth_url, status_code=302)
    response.set_cookie("linkedin_oauth_state", state, max_age=600, httponly=True, secure=True, samesite="lax")
    return response


@user_router.get("/settings/linkedin/callback")
async def linkedin_callback(
    request: Request,
    code: str = "",
    state: str = "",
    error: str = ""
):
    """Handle LinkedIn OAuth callback."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login?error=auth_required", status_code=302)

    # Check for OAuth errors
    if error:
        logger.error(f"LinkedIn OAuth error: {error}")
        return RedirectResponse(url="/settings?error=linkedin_auth_failed", status_code=302)

    # Verify CSRF state
    stored_state = request.cookies.get("linkedin_oauth_state")
    if not stored_state or stored_state != state:
        logger.error("LinkedIn OAuth state mismatch")
        return RedirectResponse(url="/settings?error=invalid_state", status_code=302)

    try:
        # Exchange code for access token
        import httpx
        from datetime import timedelta
        from src.database.models import LinkedInAccount
        from src.utils.encryption import encrypt_token

        async with httpx.AsyncClient() as client:
            token_response = await client.post(
                "https://www.linkedin.com/oauth/v2/accessToken",
                data={
                    "grant_type": "authorization_code",
                    "code": code,
                    "redirect_uri": settings.linkedin_redirect_uri,
                    "client_id": settings.linkedin_client_id,
                    "client_secret": settings.linkedin_client_secret
                },
                headers={"Content-Type": "application/x-www-form-urlencoded"}
            )

            if token_response.status_code != 200:
                logger.error(f"Token exchange failed: {token_response.status_code} - {token_response.text}")
                return RedirectResponse(url="/settings?error=token_exchange_failed", status_code=302)

            token_data = token_response.json()
            access_token = token_data["access_token"]
            expires_in = token_data.get("expires_in", 5184000)  # Default 60 days
            refresh_token = token_data.get("refresh_token")  # May not be provided
            scope = token_data.get("scope", "")

            # Get LinkedIn user info
            userinfo_response = await client.get(
                "https://api.linkedin.com/v2/userinfo",
                headers={"Authorization": f"Bearer {access_token}"}
            )

            if userinfo_response.status_code != 200:
                logger.error(f"Userinfo fetch failed: {userinfo_response.status_code}")
                return RedirectResponse(url="/settings?error=userinfo_failed", status_code=302)

            userinfo = userinfo_response.json()

            # Extract LinkedIn user data
            linkedin_user_id = userinfo.get("sub")
            linkedin_name = userinfo.get("name", "")
            linkedin_picture = userinfo.get("picture")
            cached_picture = await cache_linkedin_picture(linkedin_picture, UUID(session.user_id), http_client=client)

            # Get vanity name if available (from profile API - optional)
            linkedin_vanity_name = None
            try:
                profile_response = await client.get(
                    "https://api.linkedin.com/v2/me?projection=(id,vanityName,localizedFirstName,localizedLastName)",
                    headers={"Authorization": f"Bearer {access_token}"}
                )
                if profile_response.status_code == 200:
                    profile_data = profile_response.json()
                    linkedin_vanity_name = profile_data.get("vanityName")
            except Exception as e:
                logger.warning(f"Could not fetch vanity name: {e}")

            # Encrypt tokens
            encrypted_access = encrypt_token(access_token)
            encrypted_refresh = encrypt_token(refresh_token) if refresh_token else None

            # Check if account already exists
            existing_account = await db.get_linkedin_account(UUID(session.user_id))

            if existing_account:
                # Update existing account
                await db.update_linkedin_account(
                    existing_account.id,
                    {
                        "linkedin_user_id": linkedin_user_id,
                        "linkedin_vanity_name": linkedin_vanity_name,
                        "linkedin_name": linkedin_name,
                        "linkedin_picture": cached_picture or linkedin_picture,
                        "access_token": encrypted_access,
                        "refresh_token": encrypted_refresh,
                        "token_expires_at": datetime.now(timezone.utc) + timedelta(seconds=expires_in),
                        "granted_scopes": scope.split() if scope else [],
                        "is_active": True,
                        "last_error": None,
                        "last_error_at": None
                    }
                )
                logger.info(f"Updated LinkedIn account for user {session.user_id}")
            else:
                # Create new account
                new_account = LinkedInAccount(
                    user_id=UUID(session.user_id),
                    linkedin_user_id=linkedin_user_id,
                    linkedin_vanity_name=linkedin_vanity_name,
                    linkedin_name=linkedin_name,
                    linkedin_picture=cached_picture or linkedin_picture,
                    access_token=encrypted_access,
                    refresh_token=encrypted_refresh,
                    token_expires_at=datetime.now(timezone.utc) + timedelta(seconds=expires_in),
                    granted_scopes=scope.split() if scope else []
                )
                await db.create_linkedin_account(new_account)
                logger.info(f"Created LinkedIn account for user {session.user_id}")

            if cached_picture:
                try:
                    await db.update_profile(UUID(session.user_id), {"profile_picture": cached_picture})
                except Exception as e:
                    logger.warning(f"Failed to update profile picture: {e}")

            # Clear state cookie and redirect to settings
            response = RedirectResponse(url="/settings?success=linkedin_connected", status_code=302)
            response.delete_cookie("linkedin_oauth_state")
            return response

    except Exception as e:
        logger.exception(f"LinkedIn OAuth callback error: {e}")
        return RedirectResponse(url="/settings?error=connection_failed", status_code=302)


@user_router.post("/api/settings/linkedin/disconnect")
async def linkedin_disconnect(request: Request):
    """Remove LinkedIn account connection."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        # Get account
        linkedin_account = await db.get_linkedin_account(UUID(session.user_id))
        if not linkedin_account:
            return {"success": False, "error": "No LinkedIn account found"}

        # Optional: Revoke token with LinkedIn (not strictly necessary)
        # LinkedIn doesn't have a reliable revocation endpoint, so we just delete from DB

        # Delete from database
        await db.delete_linkedin_account(linkedin_account.id)
        logger.info(f"Disconnected LinkedIn account for user {session.user_id}")

        return {"success": True}

    except Exception as e:
        logger.exception(f"Failed to disconnect LinkedIn: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== POST INSIGHTS ====================

@user_router.post("/api/insights/refresh")
async def refresh_post_insights(request: Request):
    """Manually refresh post insights (max once per day)."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        user_id = UUID(session.user_id)
        linkedin_account = await db.get_linkedin_account(user_id)
        if not linkedin_account:
            raise HTTPException(status_code=400, detail="LinkedIn account not connected")

        profile = await db.get_profile(user_id)
        metadata = profile.metadata or {}
        today = datetime.now(timezone.utc).date().isoformat()
        last_refresh = metadata.get("post_insights_manual_refresh_date")
        if settings.insights_manual_refresh_limit_enabled and last_refresh == today:
            raise HTTPException(status_code=429, detail="Manual refresh already used today")

        # Mark refresh immediately to avoid concurrent spam
        metadata["post_insights_manual_refresh_date"] = today
        await db.update_profile(user_id, {"metadata": metadata})

        async def _bg_refresh_and_summary():
            try:
                await refresh_post_insights_for_account(db, linkedin_account)

                from datetime import date, timedelta
                since = (date.today() - timedelta(days=90)).isoformat()
                insights_posts = await db.get_post_insights_posts(user_id)
                insights_daily = await db.get_post_insights_daily(user_id, since_date=since)
                post_insights = compute_post_insights(insights_posts, insights_daily)
                if post_insights and post_insights.get("has_data"):
                    summary = await asyncio.to_thread(generate_insights_summary, post_insights)
                    if summary:
                        metadata["post_insights_summary"] = summary
                        metadata["post_insights_summary_date"] = today
                        await db.update_profile(user_id, {"metadata": metadata})
            except Exception as e:
                logger.warning(f"Manual insights refresh failed: {e}")

        asyncio.create_task(_bg_refresh_and_summary())

        return {"success": True, "refreshed_at": today, "queued": True}

    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to refresh post insights: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== COMPANY MANAGEMENT ENDPOINTS ====================

@user_router.get("/company/strategy", response_class=HTMLResponse)
async def company_strategy_page(request: Request, success: bool = False):
    """Company strategy editing page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    company = await db.get_company(UUID(session.company_id))
    strategy = company.company_strategy if company else {}

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("company_strategy.html", {
        "request": request,
        "page": "strategy",
        "session": session,
        "company": company,
        "strategy": strategy,
        "success": success,
        "profile_picture": profile_picture
    })


@user_router.post("/company/strategy")
async def company_strategy_submit(request: Request):
    """Save company strategy."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    form = await request.form()

    strategy = {
        "mission": form.get("mission", ""),
        "vision": form.get("vision", ""),
        "brand_voice": form.get("brand_voice", ""),
        "tone_guidelines": form.get("tone_guidelines", ""),
        "target_audience": form.get("target_audience", ""),
        "content_pillars": [p for p in form.getlist("content_pillar") if p],
        "dos": [d for d in form.getlist("do_item") if d],
        "donts": [d for d in form.getlist("dont_item") if d]
    }

    try:
        await db.update_company(UUID(session.company_id), {
            "company_strategy": strategy
        })
        return RedirectResponse(url="/company/strategy?success=true", status_code=302)
    except Exception as e:
        logger.error(f"Error saving company strategy: {e}")
        company = await db.get_company(UUID(session.company_id))
        return templates.TemplateResponse("company_strategy.html", {
            "request": request,
            "page": "strategy",
            "session": session,
            "company": company,
            "strategy": strategy,
            "error": str(e)
        })


@user_router.post("/company/strategy/import")
async def company_strategy_import(request: Request):
    """Import company strategy from a PDF document."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if session.account_type != "company" or not session.company_id:
        raise HTTPException(status_code=403, detail="Company account required")

    # Check token limit for companies/employees
    can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
    if not can_create:
        raise HTTPException(status_code=429, detail=error_msg)

    try:
        form = await request.form()
        upload: UploadFile = form.get("file")  # type: ignore[assignment]
        if not upload:
            raise HTTPException(status_code=400, detail="Keine Datei hochgeladen.")

        filename = upload.filename or ""
        ext = Path(filename).suffix.lower()
        if ext != ".pdf":
            raise HTTPException(status_code=400, detail="Bitte eine PDF-Datei hochladen.")

        file_bytes = await upload.read()
        max_bytes = 10 * 1024 * 1024  # 10 MB
        if len(file_bytes) > max_bytes:
            raise HTTPException(status_code=400, detail="Datei ist zu groß (max 10 MB).")

        extractor = FileExtractor()
        try:
            text = extractor.extract_text(file_bytes, filename)
        except FileExtractionError as exc:
            raise HTTPException(status_code=400, detail=str(exc)) from exc

        if len(text) > 50000:
            text = text[:50000]

        company = await db.get_company(UUID(session.company_id))
        importer = StrategyImporterAgent()
        importer.set_tracking_context(
            operation="company_strategy_import",
            user_id=session.user_id,
            company_id=session.company_id
        )

        strategy = await importer.process(text, company_name=company.name if company else None)
        return JSONResponse({"success": True, "strategy": strategy})
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Company strategy import failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.get("/company/accounts", response_class=HTMLResponse)
async def company_accounts_page(request: Request):
    """Company employee management page."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Only company owners can access
    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    company_id = UUID(session.company_id)
    employees = await db.get_company_employees(company_id)
    pending_invitations = await db.get_pending_invitations(company_id)

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("company_accounts.html", {
        "request": request,
        "page": "accounts",
        "session": session,
        "employees": employees,
        "pending_invitations": pending_invitations,
        "profile_picture": profile_picture
    })


# ==================== COMPANY MANAGE ROUTES ====================

@user_router.get("/company/manage", response_class=HTMLResponse)
async def company_manage_page(request: Request, employee_id: str = None):
    """Company content management page - manage employee posts and research."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Only company owners can access
    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    company_id = UUID(session.company_id)

    # Get all employees with completed onboarding
    all_employees = await db.get_company_employees(company_id)
    active_employees = [emp for emp in all_employees if emp.onboarding_status == "completed"]

    # Build display info for employees with correct avatar URLs (parallel)
    # Note: emp is a User object from get_company_employees which has linkedin_name and linkedin_picture
    def _make_emp_session_manage(emp):
        return UserSession(
            user_id=str(emp.id),
            linkedin_picture=emp.linkedin_picture,
            email=emp.email,
            account_type=emp.account_type.value if hasattr(emp.account_type, 'value') else emp.account_type,
            display_name=emp.display_name
        )

    emp_sessions_manage = [_make_emp_session_manage(emp) for emp in active_employees]
    emp_avatars = await asyncio.gather(*[get_user_avatar(s, emp.id) for s, emp in zip(emp_sessions_manage, active_employees)])

    active_employees_info = [
        {
            "id": str(emp.id),
            "email": emp.email,
            "display_name": emp.linkedin_name or emp.display_name or emp.email,
            "linkedin_picture": avatar_url,
            "onboarding_status": emp.onboarding_status
        }
        for emp, avatar_url in zip(active_employees, emp_avatars)
    ]

    # Selected employee data
    selected_employee = None
    employee_posts = []
    pending_posts = 0
    approved_posts = 0

    selected_permissions = None

    if employee_id:
        # Find the selected employee
        for emp in active_employees_info:
            if emp["id"] == employee_id:
                selected_employee = emp
                break

        if selected_employee:
            emp_profile, employee_posts = await asyncio.gather(
                db.get_profile(UUID(employee_id)),
                db.get_generated_posts(UUID(employee_id)),
            )
            if emp_profile:
                pending_posts = len([p for p in employee_posts if p.status in ['draft', 'pending']])
                approved_posts = len([p for p in employee_posts if p.status in ['approved', 'published']])
                selected_permissions = await get_employee_permissions_or_default(emp_profile.id, company_id)

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("company_manage.html", {
        "request": request,
        "page": "manage",
        "session": session,
        "active_employees": active_employees_info,
        "selected_employee": selected_employee,
        "employee_posts": employee_posts,
        "pending_posts": pending_posts,
        "approved_posts": approved_posts,
        "selected_permissions": selected_permissions,
        "profile_picture": profile_picture
    })


@user_router.get("/company/manage/posts", response_class=HTMLResponse)
async def company_manage_posts(request: Request, employee_id: str = None):
    """View all posts for a specific employee."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    if not employee_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Get employee info
    emp_profile = await db.get_profile(UUID(employee_id))
    if not emp_profile:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Verify employee belongs to this company
    emp_user = await db.get_user(UUID(employee_id))
    if not emp_user or str(emp_user.company_id) != session.company_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    profile = await db.get_profile(emp_profile.id)
    posts = await db.get_generated_posts(emp_profile.id)

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    permissions = await get_employee_permissions_or_default(emp_profile.id, UUID(session.company_id))

    # Enforce can_view_posts permission
    if not permissions.get("can_view_posts", True):
        return RedirectResponse(url=f"/company/manage?employee_id={employee_id}&error=no_view_permission", status_code=302)

    return templates.TemplateResponse("company_manage_posts.html", {
        "request": request,
        "page": "manage",
        "session": session,
        "employee_id": employee_id,
        "employee_name": emp_user.linkedin_name or emp_profile.display_name or emp_user.email,
        "profile": profile,
        "posts": posts,
        "total_posts": len(posts),
        "profile_picture": profile_picture,
        "permissions": permissions,
        "current_employee_id": employee_id,
    })


@user_router.get("/company/manage/post/{post_id}", response_class=HTMLResponse)
async def company_manage_post_detail(request: Request, post_id: str, employee_id: str = None):
    """View a specific post for an employee."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    if not employee_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Get employee info + post in parallel
    emp_profile, emp_user, post, profile_analysis_record = await asyncio.gather(
        db.get_profile(UUID(employee_id)),
        db.get_user(UUID(employee_id)),
        db.get_generated_post(UUID(post_id)),
        db.get_profile_analysis(UUID(employee_id)),
    )
    if not emp_profile:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Verify employee belongs to this company
    if not emp_user or str(emp_user.company_id) != session.company_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    if not post or str(post.user_id) != str(emp_profile.id):
        return RedirectResponse(url=f"/company/manage/posts?employee_id={employee_id}", status_code=302)

    profile = emp_profile  # same object - no second DB call needed

    # Get employee's avatar
    emp_session = UserSession(
        user_id=str(emp_profile.id),
        linkedin_picture=emp_user.linkedin_picture,
        email=emp_user.email,
        account_type=emp_user.account_type.value if hasattr(emp_user.account_type, 'value') else emp_user.account_type,
        display_name=emp_profile.display_name
    )
    profile_picture_url = await get_user_avatar(emp_session, emp_profile.id)
    profile_analysis = profile_analysis_record.full_analysis if profile_analysis_record else None
    style_card = None
    if profile_analysis and isinstance(profile_analysis, dict):
        from src.agents.writer import WriterAgent
        style_card = WriterAgent()._build_style_card(profile_analysis)

    # Convert media_items to dicts for JSON serialization in template
    media_items_dict = []
    if post.media_items:
        media_items_dict = [
            item.model_dump(mode='json') if hasattr(item, 'model_dump') else (item.dict() if hasattr(item, 'dict') else item)
            for item in post.media_items
        ]

    permissions = await get_employee_permissions_or_default(emp_profile.id, UUID(session.company_id))

    # Check token limit for AI quick actions
    limit_reached = False
    limit_message = ""
    if session.company_id:
        can_proceed, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_proceed
        limit_message = error_msg

    return templates.TemplateResponse("company_manage_post_detail.html", {
        "request": request,
        "page": "manage",
        "session": session,
        "employee_id": employee_id,
        "employee_name": emp_user.linkedin_name or emp_profile.display_name or emp_user.email,
        "profile": profile,
        "post": post,
        "media_items_dict": media_items_dict,
        "profile_picture_url": profile_picture_url,
        "style_card": style_card,
        "permissions": permissions,
        "current_employee_id": employee_id,
        "limit_reached": limit_reached,
        "limit_message": limit_message,
    })


@user_router.get("/company/manage/research", response_class=HTMLResponse)
async def company_manage_research(request: Request, employee_id: str = None):
    """Research page for a specific employee."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    if not employee_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Get employee info
    emp_profile = await db.get_profile(UUID(employee_id))
    if not emp_profile:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Verify employee belongs to this company
    emp_user = await db.get_user(UUID(employee_id))
    if not emp_user or str(emp_user.company_id) != session.company_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Check token limit
    limit_reached = False
    limit_message = ""
    if session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("company_manage_research.html", {
        "request": request,
        "page": "manage",
        "session": session,
        "employee_id": employee_id,
        "employee_name": emp_user.linkedin_name or emp_profile.display_name or emp_user.email,
        "user_id": str(emp_profile.id),
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "profile_picture": profile_picture
    })


@user_router.get("/company/manage/create", response_class=HTMLResponse)
async def company_manage_create(request: Request, employee_id: str = None):
    """Create post page for a specific employee."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    if not employee_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Get employee info
    emp_profile = await db.get_profile(UUID(employee_id))
    if not emp_profile:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Verify employee belongs to this company
    emp_user = await db.get_user(UUID(employee_id))
    if not emp_user or str(emp_user.company_id) != session.company_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Check token limit
    limit_reached = False
    limit_message = ""
    if session.company_id:
        can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        limit_reached = not can_create
        limit_message = error_msg

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("company_manage_create.html", {
        "request": request,
        "page": "manage",
        "session": session,
        "employee_id": employee_id,
        "employee_name": emp_user.linkedin_name or emp_profile.display_name or emp_user.email,
        "user_id": str(emp_profile.id),
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "profile_picture": profile_picture
    })


# ==================== COMPANY MANAGE CHAT-CREATE & POST TYPES ====================

@user_router.get("/company/manage/chat-create", response_class=HTMLResponse)
async def company_manage_chat_create(request: Request, employee_id: str = None):
    """Chat-create page for a specific employee in company context."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    if not employee_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    emp_profile = await db.get_profile(UUID(employee_id))
    if not emp_profile:
        return RedirectResponse(url="/company/manage", status_code=302)

    emp_user = await db.get_user(UUID(employee_id))
    if not emp_user or str(emp_user.company_id) != session.company_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Check permission
    permissions = await get_employee_permissions_or_default(emp_profile.id, UUID(session.company_id))
    if not permissions.get("can_create_posts", True):
        return RedirectResponse(url=f"/company/manage/posts?employee_id={employee_id}", status_code=302)

    # Check token limit
    limit_reached = False
    limit_message = ""
    can_create, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
    limit_reached = not can_create
    limit_message = error_msg

    # Get employee's post types
    emp_post_types = await db.get_post_types(emp_profile.id)
    if not emp_post_types:
        emp_post_types = []

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    # Load employee's saved posts for sidebar
    all_posts = await db.get_generated_posts(emp_profile.id)
    saved_posts = [post for post in all_posts if post.status not in ['scheduled', 'published']]

    return templates.TemplateResponse("company_manage_chat_create.html", {
        "request": request,
        "page": "manage_chat_create",
        "session": session,
        "employee_id": employee_id,
        "employee_name": emp_user.linkedin_name or emp_profile.display_name or emp_user.email,
        "post_types": emp_post_types,
        "profile_picture": profile_picture,
        "saved_posts": saved_posts,
        "limit_reached": limit_reached,
        "limit_message": limit_message,
        "permissions": permissions,
        "current_employee_id": employee_id,
    })


@user_router.get("/company/manage/post-types", response_class=HTMLResponse)
async def company_manage_post_types(request: Request, employee_id: str = None):
    """Post types management page for a specific employee in company context."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    if not employee_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    emp_profile = await db.get_profile(UUID(employee_id))
    if not emp_profile:
        return RedirectResponse(url="/company/manage", status_code=302)

    emp_user = await db.get_user(UUID(employee_id))
    if not emp_user or str(emp_user.company_id) != session.company_id:
        return RedirectResponse(url="/company/manage", status_code=302)

    # Check permission
    permissions = await get_employee_permissions_or_default(emp_profile.id, UUID(session.company_id))
    if not permissions.get("can_manage_post_types", True):
        return RedirectResponse(url=f"/company/manage?employee_id={employee_id}", status_code=302)

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)

    try:
        import json
        emp_id = emp_profile.id
        post_types = await db.get_post_types(emp_id, active_only=True)
        post_types_with_counts = []
        for pt in post_types:
            posts = await db.get_posts_by_type(emp_id, pt.id)
            post_types_with_counts.append({
                "post_type": {
                    "id": str(pt.id),
                    "name": pt.name,
                    "description": pt.description,
                    "strategy_weight": pt.strategy_weight,
                    "is_active": pt.is_active
                },
                "post_count": len(posts)
            })
        post_types_json = json.dumps(post_types_with_counts)
    except Exception as e:
        logger.error(f"Error loading company post types: {e}")
        import json
        post_types_with_counts = []
        post_types_json = json.dumps([])

    return templates.TemplateResponse("company_manage_post_types.html", {
        "request": request,
        "page": "manage_post_types",
        "session": session,
        "employee_id": employee_id,
        "employee_name": emp_user.linkedin_name or emp_profile.display_name or emp_user.email,
        "post_types_with_counts": post_types_with_counts,
        "post_types_json": post_types_json,
        "profile_picture": profile_picture,
        "permissions": permissions,
        "current_employee_id": employee_id,
    })


# ==================== EMPLOYEE ROUTES ====================

@user_router.get("/employee/strategy", response_class=HTMLResponse)
async def employee_strategy_page(request: Request, success: bool = False):
    """Employee profile analysis (strategy) view."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    # Only employees can access this page
    if session.account_type != "employee" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    user_id = UUID(session.user_id)
    profile_picture = await get_user_avatar(session, user_id)
    profile_analysis = await db.get_profile_analysis(user_id)

    analysis = profile_analysis.full_analysis if profile_analysis else {}
    if not isinstance(analysis, dict):
        analysis = {}

    analysis_json = json.dumps(analysis, ensure_ascii=False, indent=2)

    return templates.TemplateResponse("employee_strategy.html", {
        "request": request,
        "page": "strategy",
        "session": session,
        "profile_analysis": analysis,
        "analysis_json": analysis_json,
        "analysis_created_at": profile_analysis.created_at if profile_analysis else None,
        "success": success,
        "profile_picture": profile_picture
    })


@user_router.post("/employee/strategy", response_class=HTMLResponse)
async def employee_strategy_submit(request: Request):
    """Save edited profile analysis for employees."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "employee" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    form = await request.form()
    raw_json = (form.get("analysis_json") or "").strip()

    try:
        analysis = json.loads(raw_json) if raw_json else {}
        if not isinstance(analysis, dict):
            raise ValueError("JSON muss ein Objekt sein.")

        from src.database.models import ProfileAnalysis
        user_id = UUID(session.user_id)
        analysis_record = ProfileAnalysis(
            user_id=user_id,
            writing_style=analysis.get("writing_style", {}) or {},
            tone_analysis=analysis.get("tone_analysis", {}) or {},
            topic_patterns=analysis.get("topic_patterns", {}) or {},
            audience_insights=analysis.get("audience_insights", {}) or {},
            full_analysis=analysis
        )
        await db.save_profile_analysis(analysis_record)
        return RedirectResponse(url="/employee/strategy?success=true", status_code=302)
    except Exception as e:
        user_id = UUID(session.user_id)
        profile_picture = await get_user_avatar(session, user_id)
        return templates.TemplateResponse("employee_strategy.html", {
            "request": request,
            "page": "strategy",
            "session": session,
            "profile_analysis": {},
            "analysis_json": raw_json,
            "analysis_created_at": None,
            "error": f"Fehler beim Speichern: {e}",
            "profile_picture": profile_picture
        })


# ============================================================================
# EMPLOYEE POST TYPES MANAGEMENT
# ============================================================================

@user_router.get("/post-types/manage")
async def employee_post_types_page(request: Request):
    """Employee post types management page with strategy weight configuration."""
    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "employee":
        raise HTTPException(status_code=403, detail="Only employees can access this page")

    try:
        user_id = UUID(session.user_id)

        # Get all active post types for this employee
        post_types = await db.get_post_types(user_id, active_only=True)

        # Count posts for each post type and convert to JSON-serializable format
        post_types_with_counts = []
        for pt in post_types:
            posts = await db.get_posts_by_type(user_id, pt.id)
            post_types_with_counts.append({
                "post_type": {
                    "id": str(pt.id),
                    "name": pt.name,
                    "description": pt.description,
                    "strategy_weight": pt.strategy_weight,
                    "is_active": pt.is_active
                },
                "post_count": len(posts)
            })

        # Check if company strategy exists
        company_strategy = None
        has_strategy = False
        if session.company_id:
            company_id = UUID(session.company_id)
            company = await db.get_company(company_id)
            if company and company.company_strategy:
                company_strategy = company.company_strategy
                has_strategy = True

        profile_picture = await get_user_avatar(session, user_id)

        # Convert to JSON string for JavaScript
        import json
        post_types_json = json.dumps(post_types_with_counts)

        logger.info(f"Generated JSON for {len(post_types_with_counts)} post types")
        logger.info(f"JSON length: {len(post_types_json)} characters")
        logger.info(f"JSON preview: {post_types_json[:200] if len(post_types_json) > 200 else post_types_json}")

        return templates.TemplateResponse("employee_post_types.html", {
            "request": request,
            "page": "post_types",
            "session": session,
            "post_types_with_counts": post_types_with_counts,
            "post_types_json": post_types_json,
            "has_strategy": has_strategy,
            "company_strategy": company_strategy,
            "profile_picture": profile_picture
        })

    except Exception as e:
        logger.error(f"Error loading employee post types page: {e}")
        profile_picture = await get_user_avatar(session, UUID(session.user_id))
        import json
        return templates.TemplateResponse("employee_post_types.html", {
            "request": request,
            "page": "post_types",
            "session": session,
            "post_types_with_counts": [],
            "post_types_json": json.dumps([]),
            "has_strategy": False,
            "company_strategy": None,
            "error": str(e),
            "profile_picture": profile_picture
        })


@user_router.post("/api/employee/post-types")
async def create_employee_post_type(request: Request, background_tasks: BackgroundTasks):
    """Create a new post type for an employee."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    if session.account_type != "employee":
        return JSONResponse({"error": "Only employees can create post types"}, status_code=403)

    try:
        data = await request.json()
        user_id = UUID(session.user_id)

        # Validate required fields
        name_raw = data.get("name")
        name = name_raw.strip() if name_raw else ""
        if not name or len(name) < 3:
            return JSONResponse({"error": "Name must be at least 3 characters"}, status_code=400)

        description_raw = data.get("description")
        description = description_raw.strip() if description_raw else ""
        strategy_weight = float(data.get("strategy_weight", 0.5))

        # Validate strategy_weight range
        if not (0.0 <= strategy_weight <= 1.0):
            return JSONResponse({"error": "Strategy weight must be between 0.0 and 1.0"}, status_code=400)

        # Check if an inactive post type with this name already exists
        existing_inactive = None
        try:
            all_post_types = await db.get_post_types(user_id, active_only=False)
            existing_inactive = next((pt for pt in all_post_types if pt.name.lower() == name.lower() and not pt.is_active), None)
        except Exception as check_error:
            logger.warning(f"Could not check for inactive post types: {check_error}")

        if existing_inactive:
            # Reactivate the existing post type instead of creating a new one
            await db.update_post_type(existing_inactive.id, {
                "is_active": True,
                "description": description if description else existing_inactive.description,
                "strategy_weight": strategy_weight
            })
            created_post_type = await db.get_post_type(existing_inactive.id)
            logger.info(f"Reactivated post type '{name}' for user {user_id}")
        else:
            # Create new post type
            from src.database.models import PostType
            post_type = PostType(
                user_id=user_id,
                name=name,
                description=description if description else None,
                strategy_weight=strategy_weight,
                is_active=True
            )

            created_post_type = await db.create_post_type(post_type)
            logger.info(f"Created post type '{name}' for user {user_id}")

        return JSONResponse({
            "success": True,
            "post_type": {
                "id": str(created_post_type.id),
                "name": created_post_type.name,
                "description": created_post_type.description,
                "strategy_weight": created_post_type.strategy_weight
            }
        })

    except Exception as e:
        logger.error(f"Error creating post type: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.put("/api/employee/post-types/{post_type_id}")
async def update_employee_post_type(request: Request, post_type_id: str):
    """Update an existing post type."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    if session.account_type != "employee":
        return JSONResponse({"error": "Only employees can update post types"}, status_code=403)

    try:
        user_id = UUID(session.user_id)
        pt_id = UUID(post_type_id)

        # Check ownership
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != user_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        data = await request.json()
        updates = {}

        # Update name if provided
        if "name" in data:
            name_raw = data["name"]
            name = name_raw.strip() if name_raw else ""
            if not name or len(name) < 3:
                return JSONResponse({"error": "Name must be at least 3 characters"}, status_code=400)
            updates["name"] = name

        # Update description if provided
        if "description" in data:
            desc_raw = data["description"]
            updates["description"] = desc_raw.strip() if desc_raw else None

        # Update strategy_weight if provided
        if "strategy_weight" in data:
            strategy_weight = float(data["strategy_weight"])
            if not (0.0 <= strategy_weight <= 1.0):
                return JSONResponse({"error": "Strategy weight must be between 0.0 and 1.0"}, status_code=400)
            updates["strategy_weight"] = strategy_weight

        # Apply updates
        if updates:
            await db.update_post_type(pt_id, updates)

        return JSONResponse({"success": True})

    except Exception as e:
        logger.error(f"Error updating post type: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.delete("/api/employee/post-types/{post_type_id}")
async def delete_employee_post_type(request: Request, post_type_id: str, background_tasks: BackgroundTasks):
    """Soft delete a post type (set is_active = False)."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    if session.account_type != "employee":
        return JSONResponse({"error": "Only employees can delete post types"}, status_code=403)

    try:
        user_id = UUID(session.user_id)
        pt_id = UUID(post_type_id)

        # Check ownership
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != user_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        # Count affected posts
        posts = await db.get_posts_by_type(user_id, pt_id)
        affected_count = len(posts)

        # Soft delete
        await db.update_post_type(pt_id, {"is_active": False})

        logger.info(f"Deleted post type '{post_type.name}' for user {user_id}")

        return JSONResponse({
            "success": True,
            "affected_posts": affected_count
        })

    except Exception as e:
        logger.error(f"Error deleting post type: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)



# ============================================================================
# COMPANY MANAGING EMPLOYEE POST TYPES
# ============================================================================

@user_router.post("/api/company/manage/post-types")
async def company_create_employee_post_type(request: Request, background_tasks: BackgroundTasks):
    """Company creates a post type for an employee."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "company" or not session.company_id:
        return JSONResponse({"error": "Only company accounts can use this endpoint"}, status_code=403)

    try:
        data = await request.json()
        employee_id_str = data.get("employee_id")
        if not employee_id_str:
            return JSONResponse({"error": "employee_id required"}, status_code=400)

        emp_id = UUID(employee_id_str)
        # Verify employee belongs to company
        emp_user = await db.get_user(emp_id)
        if not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"error": "Employee not found or not in company"}, status_code=403)

        perms = await get_employee_permissions_or_default(emp_id, UUID(session.company_id))
        if not perms.get("can_manage_post_types", True):
            return JSONResponse({"error": "Keine Berechtigung zum Verwalten von Post-Typen"}, status_code=403)

        name_raw = data.get("name")
        name = name_raw.strip() if name_raw else ""
        if not name or len(name) < 3:
            return JSONResponse({"error": "Name must be at least 3 characters"}, status_code=400)

        description_raw = data.get("description")
        description = description_raw.strip() if description_raw else ""
        strategy_weight = float(data.get("strategy_weight", 0.5))
        if not (0.0 <= strategy_weight <= 1.0):
            return JSONResponse({"error": "Strategy weight must be between 0.0 and 1.0"}, status_code=400)

        # Check for inactive post type with same name
        all_post_types = await db.get_post_types(emp_id, active_only=False)
        existing_inactive = next((pt for pt in all_post_types if pt.name.lower() == name.lower() and not pt.is_active), None)

        if existing_inactive:
            await db.update_post_type(existing_inactive.id, {
                "is_active": True,
                "description": description if description else existing_inactive.description,
                "strategy_weight": strategy_weight
            })
            created_post_type = await db.get_post_type(existing_inactive.id)
        else:
            from src.database.models import PostType
            post_type = PostType(
                user_id=emp_id,
                name=name,
                description=description if description else None,
                strategy_weight=strategy_weight,
                is_active=True
            )
            created_post_type = await db.create_post_type(post_type)

        return JSONResponse({
            "success": True,
            "post_type": {
                "id": str(created_post_type.id),
                "name": created_post_type.name,
                "description": created_post_type.description,
                "strategy_weight": created_post_type.strategy_weight
            }
        })
    except Exception as e:
        logger.error(f"Error creating employee post type (company): {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.put("/api/company/manage/post-types/{post_type_id}")
async def company_update_employee_post_type(request: Request, post_type_id: str):
    """Company updates a post type for an employee."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "company" or not session.company_id:
        return JSONResponse({"error": "Only company accounts can use this endpoint"}, status_code=403)

    try:
        data = await request.json()
        employee_id_str = data.get("employee_id")
        if not employee_id_str:
            return JSONResponse({"error": "employee_id required"}, status_code=400)

        emp_id = UUID(employee_id_str)
        emp_user = await db.get_user(emp_id)
        if not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"error": "Employee not found or not in company"}, status_code=403)

        perms = await get_employee_permissions_or_default(emp_id, UUID(session.company_id))
        if not perms.get("can_manage_post_types", True):
            return JSONResponse({"error": "Keine Berechtigung"}, status_code=403)

        pt_id = UUID(post_type_id)
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != emp_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        updates = {}
        if "name" in data:
            name = data["name"].strip() if data["name"] else ""
            if not name or len(name) < 3:
                return JSONResponse({"error": "Name must be at least 3 characters"}, status_code=400)
            updates["name"] = name
        if "description" in data:
            desc = data["description"]
            updates["description"] = desc.strip() if desc else None
        if "strategy_weight" in data:
            sw = float(data["strategy_weight"])
            if not (0.0 <= sw <= 1.0):
                return JSONResponse({"error": "Strategy weight must be between 0.0 and 1.0"}, status_code=400)
            updates["strategy_weight"] = sw

        if updates:
            await db.update_post_type(pt_id, updates)
        return JSONResponse({"success": True})
    except Exception as e:
        logger.error(f"Error updating employee post type (company): {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.delete("/api/company/manage/post-types/{post_type_id}")
async def company_delete_employee_post_type(request: Request, post_type_id: str, employee_id: str = None):
    """Company soft-deletes a post type for an employee."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "company" or not session.company_id:
        return JSONResponse({"error": "Only company accounts can use this endpoint"}, status_code=403)
    if not employee_id:
        return JSONResponse({"error": "employee_id required"}, status_code=400)

    try:
        emp_id = UUID(employee_id)
        emp_user = await db.get_user(emp_id)
        if not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"error": "Employee not found or not in company"}, status_code=403)

        perms = await get_employee_permissions_or_default(emp_id, UUID(session.company_id))
        if not perms.get("can_manage_post_types", True):
            return JSONResponse({"error": "Keine Berechtigung"}, status_code=403)

        pt_id = UUID(post_type_id)
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != emp_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        posts = await db.get_posts_by_type(emp_id, pt_id)
        await db.update_post_type(pt_id, {"is_active": False})
        return JSONResponse({"success": True, "affected_posts": len(posts)})
    except Exception as e:
        logger.error(f"Error deleting employee post type (company): {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/company/manage/post-types/save-all")
async def company_save_all_employee_post_types(request: Request, background_tasks: BackgroundTasks):
    """Company triggers re-categorization for employee post types."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "company" or not session.company_id:
        return JSONResponse({"error": "Only company accounts can use this endpoint"}, status_code=403)

    try:
        data = await request.json()
        employee_id_str = data.get("employee_id")
        has_structural_changes = data.get("has_structural_changes", False)

        if not employee_id_str:
            return JSONResponse({"error": "employee_id required"}, status_code=400)

        emp_id = UUID(employee_id_str)
        emp_user = await db.get_user(emp_id)
        if not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"error": "Employee not found or not in company"}, status_code=403)

        if has_structural_changes:
            categorization_job = await job_manager.create_job(
                job_type=JobType.POST_CATEGORIZATION,
                user_id=str(emp_id)
            )
            analysis_job = await job_manager.create_job(
                job_type=JobType.POST_TYPE_ANALYSIS,
                user_id=str(emp_id)
            )
            background_tasks.add_task(run_post_recategorization, emp_id, categorization_job.id)
            background_tasks.add_task(run_post_type_analysis, emp_id, analysis_job.id)
            return JSONResponse({"success": True, "recategorized": True})

        return JSONResponse({"success": True, "recategorized": False})
    except Exception as e:
        logger.error(f"Error in company save-all post types: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.get("/api/employee/post-types/{post_type_id}/posts")
async def employee_list_post_type_posts(request: Request, post_type_id: str):
    """List posts assigned to a post type."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "employee":
        return JSONResponse({"error": "Only employees can access this endpoint"}, status_code=403)

    try:
        user_id = UUID(session.user_id)
        pt_id = UUID(post_type_id)
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != user_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        posts = await db.get_posts_by_type(user_id, pt_id)
        return JSONResponse({
            "success": True,
            "posts": [
                {
                    "id": str(p.id),
                    "post_text": p.post_text,
                    "post_date": p.post_date.isoformat() if p.post_date else None,
                    "post_url": p.post_url,
                    "classification_method": p.classification_method,
                }
                for p in posts
            ]
        })
    except Exception as e:
        logger.error(f"Error listing employee post type posts: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/employee/post-types/posts")
async def employee_add_manual_post_to_type(request: Request):
    """Add a manual post and assign it to a post type."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "employee":
        return JSONResponse({"error": "Only employees can add posts here"}, status_code=403)

    try:
        data = await request.json()
        user_id = UUID(session.user_id)
        pt_id = UUID(data.get("post_type_id"))
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != user_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        post_text = (data.get("post_text") or "").strip()
        if len(post_text) < 20:
            return JSONResponse({"error": "Post muss mindestens 20 Zeichen lang sein"}, status_code=400)

        from uuid import uuid4
        from src.database.models import LinkedInPost

        manual_post = LinkedInPost(
            user_id=user_id,
            post_text=post_text,
            post_url=f"manual://{uuid4()}",
            post_date=datetime.now(timezone.utc),
            post_type_id=pt_id,
            classification_method="manual",
            classification_confidence=1.0,
            raw_data={"source": "manual", "manual_entry": True}
        )
        saved_posts = await db.save_linkedin_posts([manual_post])
        saved = saved_posts[0] if saved_posts else None

        return JSONResponse({
            "success": True,
            "post": {
                "id": str(saved.id) if saved and saved.id else None,
                "post_text": saved.post_text if saved else post_text,
                "post_date": saved.post_date.isoformat() if saved and saved.post_date else None,
            }
        })
    except Exception as e:
        logger.error(f"Error adding manual post for employee post type: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.delete("/api/employee/post-types/{post_type_id}/posts/{post_id}")
async def employee_delete_post_from_type(request: Request, post_type_id: str, post_id: str):
    """Delete a post assigned to a post type."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "employee":
        return JSONResponse({"error": "Only employees can delete posts here"}, status_code=403)

    try:
        user_id = UUID(session.user_id)
        pt_id = UUID(post_type_id)
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != user_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        post = await db.get_linkedin_post(UUID(post_id))
        if not post or post.user_id != user_id or post.post_type_id != pt_id:
            return JSONResponse({"error": "Post not found or access denied"}, status_code=404)

        await db.delete_linkedin_post(UUID(post_id))
        return JSONResponse({"success": True})
    except Exception as e:
        logger.error(f"Error deleting employee post from type: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.get("/api/company/manage/post-types/{post_type_id}/posts")
async def company_list_employee_post_type_posts(request: Request, post_type_id: str, employee_id: str):
    """Company lists posts assigned to an employee's post type."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "company" or not session.company_id:
        return JSONResponse({"error": "Only company accounts can access this endpoint"}, status_code=403)

    try:
        emp_id = UUID(employee_id)
        emp_user = await db.get_user(emp_id)
        if not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"error": "Employee not found or not in company"}, status_code=403)

        pt_id = UUID(post_type_id)
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != emp_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        posts = await db.get_posts_by_type(emp_id, pt_id)
        return JSONResponse({
            "success": True,
            "posts": [
                {
                    "id": str(p.id),
                    "post_text": p.post_text,
                    "post_date": p.post_date.isoformat() if p.post_date else None,
                    "post_url": p.post_url,
                    "classification_method": p.classification_method,
                }
                for p in posts
            ]
        })
    except Exception as e:
        logger.error(f"Error listing company-managed employee post type posts: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/company/manage/post-types/posts")
async def company_add_manual_post_to_employee_type(request: Request):
    """Company adds a manual post for an employee and assigns it to a post type."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "company" or not session.company_id:
        return JSONResponse({"error": "Only company accounts can add posts here"}, status_code=403)

    try:
        data = await request.json()
        emp_id = UUID(data.get("employee_id"))
        emp_user = await db.get_user(emp_id)
        if not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"error": "Employee not found or not in company"}, status_code=403)

        perms = await get_employee_permissions_or_default(emp_id, UUID(session.company_id))
        if not perms.get("can_manage_post_types", True):
            return JSONResponse({"error": "Keine Berechtigung"}, status_code=403)

        pt_id = UUID(data.get("post_type_id"))
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != emp_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        post_text = (data.get("post_text") or "").strip()
        if len(post_text) < 20:
            return JSONResponse({"error": "Post muss mindestens 20 Zeichen lang sein"}, status_code=400)

        from uuid import uuid4
        from src.database.models import LinkedInPost

        manual_post = LinkedInPost(
            user_id=emp_id,
            post_text=post_text,
            post_url=f"manual://{uuid4()}",
            post_date=datetime.now(timezone.utc),
            post_type_id=pt_id,
            classification_method="manual",
            classification_confidence=1.0,
            raw_data={"source": "manual", "manual_entry": True}
        )
        saved_posts = await db.save_linkedin_posts([manual_post])
        saved = saved_posts[0] if saved_posts else None

        return JSONResponse({
            "success": True,
            "post": {
                "id": str(saved.id) if saved and saved.id else None,
                "post_text": saved.post_text if saved else post_text,
                "post_date": saved.post_date.isoformat() if saved and saved.post_date else None,
            }
        })
    except Exception as e:
        logger.error(f"Error adding manual post for company-managed employee post type: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.delete("/api/company/manage/post-types/{post_type_id}/posts/{post_id}")
async def company_delete_post_from_employee_type(request: Request, post_type_id: str, post_id: str, employee_id: str):
    """Company deletes a post assigned to an employee's post type."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)
    if session.account_type != "company" or not session.company_id:
        return JSONResponse({"error": "Only company accounts can delete posts here"}, status_code=403)

    try:
        emp_id = UUID(employee_id)
        emp_user = await db.get_user(emp_id)
        if not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"error": "Employee not found or not in company"}, status_code=403)

        perms = await get_employee_permissions_or_default(emp_id, UUID(session.company_id))
        if not perms.get("can_manage_post_types", True):
            return JSONResponse({"error": "Keine Berechtigung"}, status_code=403)

        pt_id = UUID(post_type_id)
        post_type = await db.get_post_type(pt_id)
        if not post_type or post_type.user_id != emp_id:
            return JSONResponse({"error": "Post type not found or access denied"}, status_code=404)

        post = await db.get_linkedin_post(UUID(post_id))
        if not post or post.user_id != emp_id or post.post_type_id != pt_id:
            return JSONResponse({"error": "Post not found or access denied"}, status_code=404)

        await db.delete_linkedin_post(UUID(post_id))
        return JSONResponse({"success": True})
    except Exception as e:
        logger.error(f"Error deleting company-managed employee post from type: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/employee/post-types/save-all")
async def save_all_and_reanalyze(request: Request, background_tasks: BackgroundTasks):
    """Save all changes and conditionally trigger re-categorization based on structural changes."""
    session = require_user_session(request)
    if not session:
        return JSONResponse({"error": "Not authenticated"}, status_code=401)

    if session.account_type != "employee":
        return JSONResponse({"error": "Only employees can trigger re-analysis"}, status_code=403)

    try:
        data = await request.json()
        has_structural_changes = data.get("has_structural_changes", False)

        user_id = UUID(session.user_id)
        user_id_str = str(user_id)

        # Only trigger re-categorization and analysis if there were structural changes
        if has_structural_changes:
            # Create background job for post re-categorization (ALL posts)
            categorization_job = await job_manager.create_job(
                job_type=JobType.POST_CATEGORIZATION,
                user_id=user_id_str
            )

            # Create background job for post type analysis
            analysis_job = await job_manager.create_job(
                job_type=JobType.POST_TYPE_ANALYSIS,
                user_id=user_id_str
            )

            # Start background tasks
            background_tasks.add_task(run_post_recategorization, user_id, categorization_job.id)
            background_tasks.add_task(run_post_type_analysis, user_id, analysis_job.id)

            logger.info(f"Started re-analysis jobs for user {user_id}: categorization={categorization_job.id}, analysis={analysis_job.id}")

            return JSONResponse({
                "success": True,
                "recategorized": True,
                "categorization_job_id": str(categorization_job.id),
                "analysis_job_id": str(analysis_job.id)
            })
        else:
            logger.info(f"No structural changes for user {user_id}, skipping re-analysis")
            return JSONResponse({
                "success": True,
                "recategorized": False,
                "message": "Nur Weight-Updates, keine Rekategorisierung notwendig"
            })

    except Exception as e:
        logger.error(f"Error in save-all: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@user_router.post("/api/employee/chat/generate")
async def chat_generate_post(request: Request):
    """Generate initial post from chat message."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        data = await request.json()
        message = data.get("message", "").strip()
        post_type_id = data.get("post_type_id")

        if not message:
            return JSONResponse({"success": False, "error": "Nachricht erforderlich"})

        if not post_type_id:
            return JSONResponse({"success": False, "error": "Post-Typ erforderlich"})

        # Check token limit for companies/employees
        if session.account_type in ("company", "employee") and session.company_id:
            can_proceed, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
            if not can_proceed:
                return JSONResponse({"success": False, "token_limit_exceeded": True, "error": error_msg})

        user_id = UUID(session.user_id)

        # Get post type info
        post_type = await db.get_post_type(UUID(post_type_id))
        if not post_type:
            return JSONResponse({"success": False, "error": "Post-Typ nicht gefunden"})

        # Get profile analysis
        profile_analysis = await db.get_profile_analysis(user_id)
        if not profile_analysis:
            return JSONResponse({"success": False, "error": "Profil-Analyse nicht gefunden"})

        # Get company strategy if available
        company_strategy = None
        profile = await db.get_profile(user_id)
        if profile and profile.company_id:
            company = await db.get_company(profile.company_id)
            if company and company.company_strategy:
                company_strategy = company.company_strategy

        # Get example posts for style reference
        linkedin_posts = await db.get_posts_by_type(user_id, UUID(post_type_id))
        if len(linkedin_posts) < 3:
            linkedin_posts = await db.get_linkedin_posts(user_id)

        example_post_texts = [
            post.post_text for post in linkedin_posts
            if post.post_text and len(post.post_text) > 100
        ][:10]

        # Generate post using writer agent with user's content as primary focus
        from src.agents.writer import WriterAgent
        writer = WriterAgent()
        writer.set_tracking_context(
            operation='post_creation',
            user_id=session.user_id,
            company_id=session.company_id
        )

        # Create a topic structure from user's message
        topic = {
            "title": message[:100],
            "fact": message,
            "relevance": "User-specified content"
        }

        strategy_weight = orchestrator._get_effective_strategy_weight(
            base_weight=post_type.strategy_weight,
            post_type=post_type,
            post_type_analysis=post_type.analysis if post_type else None
        )

        plan = await orchestrator.generate_post_plan(
            topic=topic,
            profile_analysis=profile_analysis.full_analysis,
            company_strategy=company_strategy,
            strategy_weight=strategy_weight,
            user_thoughts=message,
            post_type_analysis=post_type.analysis if post_type and post_type.analysis else None
        )
        if plan:
            topic["content_plan"] = plan

        # Generate post
        post_content = await writer.process(
            topic=topic,
            profile_analysis=profile_analysis.full_analysis,
            example_posts=example_post_texts,
            post_type=post_type,
            user_thoughts=message,  # CRITICAL: User's input as primary content
            company_strategy=company_strategy,
            strategy_weight=strategy_weight
        )
        post_content = sanitize_post_content(post_content, profile_analysis.full_analysis)

        # Run critic + one revision pass for chat flow quality parity
        critic_result = await orchestrator.critic.process(
            post=post_content,
            profile_analysis=profile_analysis.full_analysis,
            topic=topic,
            example_posts=example_post_texts,
            iteration=1,
            max_iterations=2
        )
        critic_result = orchestrator._normalize_critic_scores(critic_result)
        if not critic_result.get("approved", False):
            post_content = await writer.process(
                topic=topic,
                profile_analysis=profile_analysis.full_analysis,
                feedback=critic_result.get("feedback", ""),
                previous_version=post_content,
                example_posts=example_post_texts,
                critic_result=critic_result,
                post_type=post_type,
                user_thoughts=message,
                company_strategy=company_strategy,
                strategy_weight=strategy_weight
            )
            post_content = sanitize_post_content(post_content, profile_analysis.full_analysis)
            critic_result = await orchestrator.critic.process(
                post=post_content,
                profile_analysis=profile_analysis.full_analysis,
                topic=topic,
                example_posts=example_post_texts,
                iteration=2,
                max_iterations=2
            )
            critic_result = orchestrator._normalize_critic_scores(critic_result)

        # Quality checks + final polish (same as wizard)
        if settings.quality_refiner_enabled:
            quality_checks = await orchestrator._run_quality_checks(post_content, example_post_texts)
            grammar_errors = quality_checks['grammar_check'].get('error_count', 0)
            style_similarity = quality_checks['style_check'].get('avg_similarity', 1.0)
            readability_passed = quality_checks['readability_check'].get('passed', True)
            needs_polish = (
                grammar_errors > 0 or
                style_similarity < 0.75 or
                not readability_passed
            )
            if needs_polish:
                post_content = await orchestrator.quality_refiner.final_polish(
                    post=post_content,
                    quality_checks=quality_checks,
                    profile_analysis=profile_analysis.full_analysis,
                    example_posts=example_post_texts
                )
                post_content = sanitize_post_content(post_content, profile_analysis.full_analysis)

        # Generate conversation ID
        import uuid
        conversation_id = str(uuid.uuid4())

        return JSONResponse({
            "success": True,
            "post": post_content,
            "conversation_id": conversation_id,
            "explanation": "Hier ist dein erster Entwurf basierend auf deiner Beschreibung:"
        })

    except Exception as e:
        logger.error(f"Error generating chat post: {e}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


@user_router.post("/api/employee/chat/refine")
async def chat_refine_post(request: Request):
    """Refine existing post based on user feedback."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        data = await request.json()
        message = data.get("message", "").strip()
        current_post = data.get("current_post", "")
        post_type_id = data.get("post_type_id")
        chat_history = data.get("chat_history", [])

        if not message:
            return JSONResponse({"success": False, "error": "Nachricht erforderlich"})

        if not current_post:
            return JSONResponse({"success": False, "error": "Kein Post zum Verfeinern vorhanden"})

        if not post_type_id:
            return JSONResponse({"success": False, "error": "Post-Typ erforderlich"})

        # Check token limit for companies/employees
        if session.account_type in ("company", "employee") and session.company_id:
            can_proceed, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
            if not can_proceed:
                return JSONResponse({"success": False, "token_limit_exceeded": True, "error": error_msg})

        user_id = UUID(session.user_id)

        # Get post type info
        post_type = await db.get_post_type(UUID(post_type_id))
        if not post_type:
            return JSONResponse({"success": False, "error": "Post-Typ nicht gefunden"})

        # Get profile analysis
        profile_analysis = await db.get_profile_analysis(user_id)
        if not profile_analysis:
            return JSONResponse({"success": False, "error": "Profil-Analyse nicht gefunden"})

        # Ensure full_analysis is a dict
        full_analysis = profile_analysis.full_analysis if profile_analysis.full_analysis else {}
        if not isinstance(full_analysis, dict):
            logger.warning(f"full_analysis is not a dict: {type(full_analysis)}")
            full_analysis = {}

        # Get company strategy if available
        company_strategy = None
        profile = await db.get_profile(user_id)
        if profile and profile.company_id:
            company = await db.get_company(profile.company_id)
            if company and company.company_strategy:
                company_strategy = company.company_strategy
                # Ensure it's a dict
                if not isinstance(company_strategy, dict):
                    logger.warning(f"company_strategy is not a dict: {type(company_strategy)}")
                    company_strategy = None

        # Get example posts
        linkedin_posts = await db.get_posts_by_type(user_id, UUID(post_type_id))
        if len(linkedin_posts) < 3:
            linkedin_posts = await db.get_linkedin_posts(user_id)

        example_post_texts = [
            post.post_text for post in linkedin_posts
            if post.post_text and len(post.post_text) > 100
        ][:10]

        # Refine post using writer with feedback
        from src.agents.writer import WriterAgent
        writer = WriterAgent()
        writer.set_tracking_context(
            operation='post_creation',
            user_id=session.user_id,
            company_id=session.company_id
        )

        topic = {
            "title": "Chat refinement",
            "fact": message,
            "relevance": "User refinement request"
        }

        strategy_weight = orchestrator._get_effective_strategy_weight(
            base_weight=getattr(post_type, 'strategy_weight', 0.5),
            post_type=post_type,
            post_type_analysis=post_type.analysis if post_type else None
        )

        plan = await orchestrator.generate_post_plan(
            topic=topic,
            profile_analysis=full_analysis,
            company_strategy=company_strategy,
            strategy_weight=strategy_weight,
            user_thoughts=message,
            post_type_analysis=post_type.analysis if post_type and post_type.analysis else None
        )
        if plan:
            topic["content_plan"] = plan

        # Use writer's revision capability
        refined_post = await writer.process(
            topic=topic,
            profile_analysis=full_analysis,
            example_posts=example_post_texts,
            feedback=message,  # User's refinement instruction
            previous_version=current_post,
            post_type=post_type,
            user_thoughts=message,
            company_strategy=company_strategy,
            strategy_weight=strategy_weight
        )
        refined_post = sanitize_post_content(refined_post, full_analysis)

        # Critic + quality checks for chat refine parity
        critic_result = await orchestrator.critic.process(
            post=refined_post,
            profile_analysis=full_analysis,
            topic=topic,
            example_posts=example_post_texts,
            iteration=1,
            max_iterations=2
        )
        critic_result = orchestrator._normalize_critic_scores(critic_result)
        if not critic_result.get("approved", False):
            refined_post = await writer.process(
                topic=topic,
                profile_analysis=full_analysis,
                feedback=critic_result.get("feedback", ""),
                previous_version=refined_post,
                example_posts=example_post_texts,
                critic_result=critic_result,
                post_type=post_type,
                user_thoughts=message,
                company_strategy=company_strategy,
                strategy_weight=strategy_weight
            )
            refined_post = sanitize_post_content(refined_post, full_analysis)

            critic_result = await orchestrator.critic.process(
                post=refined_post,
                profile_analysis=full_analysis,
                topic=topic,
                example_posts=example_post_texts,
                iteration=2,
                max_iterations=2
            )
            critic_result = orchestrator._normalize_critic_scores(critic_result)

        if settings.quality_refiner_enabled:
            quality_checks = await orchestrator._run_quality_checks(refined_post, example_post_texts)
            grammar_errors = quality_checks['grammar_check'].get('error_count', 0)
            style_similarity = quality_checks['style_check'].get('avg_similarity', 1.0)
            readability_passed = quality_checks['readability_check'].get('passed', True)
            needs_polish = (
                grammar_errors > 0 or
                style_similarity < 0.75 or
                not readability_passed
            )
            if needs_polish:
                refined_post = await orchestrator.quality_refiner.final_polish(
                    post=refined_post,
                    quality_checks=quality_checks,
                    profile_analysis=full_analysis,
                    example_posts=example_post_texts
                )
                refined_post = sanitize_post_content(refined_post, full_analysis)

        return JSONResponse({
            "success": True,
            "post": refined_post,
            "conversation_id": data.get("conversation_id"),
            "explanation": "Ich habe den Post angepasst:"
        })

    except Exception as e:
        import traceback
        logger.error(f"Error refining chat post: {e}")
        logger.error(f"Traceback: {traceback.format_exc()}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


@user_router.post("/api/employee/chat/save")
async def chat_save_post(request: Request):
    """Save chat-generated post to database."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        data = await request.json()
        post_content = sanitize_post_content(data.get("post_content", "").strip())
        post_type_id = data.get("post_type_id")
        chat_history = data.get("chat_history", [])

        if not post_content:
            return JSONResponse({"success": False, "error": "Post-Inhalt erforderlich"})

        if not post_type_id:
            return JSONResponse({"success": False, "error": "Post-Typ erforderlich"})

        user_id = UUID(session.user_id)

        # Extract title from first sentence of post
        first_sentence = post_content.split('\n')[0].strip()
        if len(first_sentence) > 100:
            title = first_sentence[:97] + "..."
        else:
            title = first_sentence if first_sentence else "Chat-generierter Post"

        # Create GeneratedPost with status draft
        from src.database.models import GeneratedPost
        import uuid as uuid_lib

        post_id = uuid_lib.uuid4()

        # Extract all AI-generated versions from chat history
        writer_versions = []
        critic_feedback_list = []

        for item in chat_history:
            if 'ai' in item and item['ai']:
                writer_versions.append(sanitize_post_content(item['ai']))
                # Store user feedback as "critic feedback"
                if 'user' in item and item['user']:
                    critic_feedback_list.append({
                        'feedback': item['user'],
                        'explanation': item.get('explanation', '')
                    })

        # Add final version
        writer_versions.append(post_content)

        num_iterations = len(writer_versions)

        generated_post = GeneratedPost(
            id=post_id,
            user_id=user_id,
            post_content=post_content,
            post_type_id=UUID(post_type_id),
            status="draft",
            iterations=num_iterations,
            writer_versions=writer_versions,  # All iterations saved here
            critic_feedback=critic_feedback_list,  # User feedback saved here
            topic_title=title,
            created_at=datetime.now(timezone.utc)
        )

        saved_post = await db.save_generated_post(generated_post)

        return JSONResponse({
            "success": True,
            "post_id": str(saved_post.id),
            "message": "Post erfolgreich gespeichert"
        })

    except Exception as e:
        logger.error(f"Error saving chat post: {e}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


@user_router.get("/api/employee/chat/history/{post_id}")
async def get_chat_history(request: Request, post_id: str):
    """Get chat history for a saved post."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        user_id = UUID(session.user_id)
        post_uuid = UUID(post_id)

        # Fetch post
        post = await db.get_generated_post(post_uuid)
        if not post:
            return JSONResponse({"success": False, "error": "Post nicht gefunden"}, status_code=404)

        # Verify ownership
        if post.user_id != user_id:
            return JSONResponse({"success": False, "error": "Nicht autorisiert"}, status_code=403)

        # Reconstruct chat history from writer_versions and critic_feedback
        chat_history = []

        # First version: AI generates initial post (no user message)
        if post.writer_versions and len(post.writer_versions) > 0:
            first_explanation = "Hier ist dein erster Entwurf:"
            # Check if first critic feedback has explanation (from AI)
            if post.critic_feedback and len(post.critic_feedback) > 0:
                first_explanation = post.critic_feedback[0].get('explanation', first_explanation)

            chat_history.append({
                "user": "",  # No user message for first generation
                "ai": post.writer_versions[0],
                "explanation": first_explanation
            })

        # Subsequent versions: User feedback → AI refined version
        for i in range(1, len(post.writer_versions)):
            user_message = ""
            explanation = "Hier ist die überarbeitete Version:"

            # Get user feedback from critic_feedback (offset by 1, since first is for initial)
            if i <= len(post.critic_feedback):
                feedback_item = post.critic_feedback[i - 1]
                user_message = feedback_item.get('feedback', '')
                explanation = feedback_item.get('explanation', explanation)

            chat_history.append({
                "user": user_message,
                "ai": post.writer_versions[i],
                "explanation": explanation
            })

        return JSONResponse({
            "success": True,
            "chat_history": chat_history,
            "post": post.post_content,
            "post_type_id": str(post.post_type_id) if post.post_type_id else None,
            "topic_title": post.topic_title
        })

    except ValueError:
        return JSONResponse({"success": False, "error": "Ungültige Post-ID"}, status_code=400)
    except Exception as e:
        logger.error(f"Error fetching chat history: {e}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


@user_router.put("/api/employee/chat/update/{post_id}")
async def update_chat_post(request: Request, post_id: str):
    """Update an existing post with new chat conversation."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        user_id = UUID(session.user_id)
        post_uuid = UUID(post_id)

        data = await request.json()
        post_content = sanitize_post_content(data.get("post_content", "").strip())
        chat_history = data.get("chat_history", [])

        if not post_content:
            return JSONResponse({"success": False, "error": "Post-Inhalt erforderlich"})

        # Fetch existing post
        post = await db.get_generated_post(post_uuid)
        if not post:
            return JSONResponse({"success": False, "error": "Post nicht gefunden"}, status_code=404)

        # Verify ownership
        if post.user_id != user_id:
            return JSONResponse({"success": False, "error": "Nicht autorisiert"}, status_code=403)

        # Extract all AI-generated versions from chat history
        writer_versions = []
        critic_feedback_list = []

        for item in chat_history:
            if 'ai' in item and item['ai']:
                writer_versions.append(sanitize_post_content(item['ai']))
                # Store user feedback as "critic feedback"
                if 'user' in item and item['user']:
                    critic_feedback_list.append({
                        'feedback': item['user'],
                        'explanation': item.get('explanation', '')
                    })

        # Prepare update data
        updates = {
            'post_content': post_content,
            'writer_versions': writer_versions,
            'critic_feedback': critic_feedback_list,
            'iterations': len(writer_versions)
        }

        # Update the post using the correct method
        updated_post = await db.update_generated_post(post_uuid, updates)

        return JSONResponse({
            "success": True,
            "post_id": str(updated_post.id),
            "message": "Post erfolgreich aktualisiert"
        })

    except ValueError:
        return JSONResponse({"success": False, "error": "Ungültige Post-ID"}, status_code=400)
    except Exception as e:
        logger.error(f"Error updating chat post: {e}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


# ==================== COMPANY MANAGE CHAT API (PROXY FOR EMPLOYEE) ====================

@user_router.post("/api/company/manage/chat/generate")
async def company_chat_generate_post(request: Request):
    """Generate a post for an employee via company context."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if session.account_type != "company" or not session.company_id:
        raise HTTPException(status_code=403, detail="Company account required")

    try:
        data = await request.json()
        employee_id = data.get("employee_id")
        message = data.get("message", "").strip()
        post_type_id = data.get("post_type_id")

        if not employee_id or not message or not post_type_id:
            return JSONResponse({"success": False, "error": "employee_id, message und post_type_id erforderlich"})

        # Verify employee belongs to this company
        emp_profile = await db.get_profile(UUID(employee_id))
        emp_user = await db.get_user(UUID(employee_id))
        if not emp_profile or not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"success": False, "error": "Mitarbeiter nicht gefunden"}, status_code=404)

        # Check permission
        perms = await get_employee_permissions_or_default(emp_profile.id, UUID(session.company_id))
        if not perms.get("can_create_posts", True):
            return JSONResponse({"success": False, "error": "Keine Berechtigung"}, status_code=403)

        # Check token limit
        can_proceed, error_msg, _, _ = await db.check_company_token_limit(UUID(session.company_id))
        if not can_proceed:
            return JSONResponse({"success": False, "token_limit_exceeded": True, "error": error_msg})

        user_id = emp_profile.id

        post_type = await db.get_post_type(UUID(post_type_id))
        if not post_type:
            return JSONResponse({"success": False, "error": "Post-Typ nicht gefunden"})

        profile_analysis = await db.get_profile_analysis(user_id)
        if not profile_analysis:
            return JSONResponse({"success": False, "error": "Profil-Analyse nicht gefunden. Bitte führe erst eine Profilanalyse durch."})

        company = await db.get_company(UUID(session.company_id))
        company_strategy = company.company_strategy if company else None

        linkedin_posts = await db.get_posts_by_type(user_id, UUID(post_type_id))
        if len(linkedin_posts) < 3:
            linkedin_posts = await db.get_linkedin_posts(user_id)

        example_post_texts = [
            post.post_text for post in linkedin_posts
            if post.post_text and len(post.post_text) > 100
        ][:10]

        from src.agents.writer import WriterAgent
        import uuid
        writer = WriterAgent()
        writer.set_tracking_context(
            operation='post_creation',
            user_id=session.user_id,
            company_id=session.company_id
        )

        topic = {"title": message[:100], "fact": message, "relevance": "Company-created content"}

        strategy_weight = orchestrator._get_effective_strategy_weight(
            base_weight=post_type.strategy_weight,
            post_type=post_type,
            post_type_analysis=post_type.analysis if post_type else None
        )

        plan = await orchestrator.generate_post_plan(
            topic=topic,
            profile_analysis=profile_analysis.full_analysis,
            company_strategy=company_strategy,
            strategy_weight=strategy_weight,
            user_thoughts=message,
            post_type_analysis=post_type.analysis if post_type and post_type.analysis else None
        )
        if plan:
            topic["content_plan"] = plan
        post_content = await writer.process(
            topic=topic,
            profile_analysis=profile_analysis.full_analysis,
            example_posts=example_post_texts,
            post_type=post_type,
            user_thoughts=message,
            company_strategy=company_strategy,
            strategy_weight=strategy_weight
        )
        post_content = sanitize_post_content(post_content, profile_analysis.full_analysis)

        # Run critic + one revision pass for chat flow quality parity
        critic_result = await orchestrator.critic.process(
            post=post_content,
            profile_analysis=profile_analysis.full_analysis,
            topic=topic,
            example_posts=example_post_texts,
            iteration=1,
            max_iterations=2
        )
        if not critic_result.get("approved", False):
            post_content = await writer.process(
                topic=topic,
                profile_analysis=profile_analysis.full_analysis,
                feedback=critic_result.get("feedback", ""),
                previous_version=post_content,
                example_posts=example_post_texts,
                critic_result=critic_result,
                post_type=post_type,
                user_thoughts=message,
                company_strategy=company_strategy,
                strategy_weight=strategy_weight
            )
            post_content = sanitize_post_content(post_content, profile_analysis.full_analysis)

        if settings.quality_refiner_enabled:
            quality_checks = await orchestrator._run_quality_checks(post_content, example_post_texts)
            grammar_errors = quality_checks['grammar_check'].get('error_count', 0)
            style_similarity = quality_checks['style_check'].get('avg_similarity', 1.0)
            readability_passed = quality_checks['readability_check'].get('passed', True)
            needs_polish = (
                grammar_errors > 0 or
                style_similarity < 0.75 or
                not readability_passed
            )
            if needs_polish:
                post_content = await orchestrator.quality_refiner.final_polish(
                    post=post_content,
                    quality_checks=quality_checks,
                    profile_analysis=profile_analysis.full_analysis,
                    example_posts=example_post_texts
                )
                post_content = sanitize_post_content(post_content, profile_analysis.full_analysis)

        return JSONResponse({
            "success": True,
            "post": post_content,
            "conversation_id": str(uuid.uuid4()),
            "explanation": "Hier ist der erste Entwurf basierend auf der Beschreibung:"
        })

    except Exception as e:
        logger.error(f"Error generating company chat post: {e}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


@user_router.post("/api/company/manage/chat/save")
async def company_chat_save_post(request: Request):
    """Save a chat-generated post for an employee."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if session.account_type != "company" or not session.company_id:
        raise HTTPException(status_code=403, detail="Company account required")

    try:
        data = await request.json()
        employee_id = data.get("employee_id")
        post_content = sanitize_post_content(data.get("post_content", "").strip())
        post_type_id = data.get("post_type_id")
        chat_history = data.get("chat_history", [])
        topic_title = data.get("topic_title", post_content[:80] if post_content else "Chat Post")

        if not employee_id or not post_content:
            return JSONResponse({"success": False, "error": "employee_id und post_content erforderlich"})

        emp_profile = await db.get_profile(UUID(employee_id))
        emp_user = await db.get_user(UUID(employee_id))
        if not emp_profile or not emp_user or str(emp_user.company_id) != session.company_id:
            return JSONResponse({"success": False, "error": "Mitarbeiter nicht gefunden"}, status_code=404)

        perms = await get_employee_permissions_or_default(emp_profile.id, UUID(session.company_id))
        if not perms.get("can_create_posts", True):
            return JSONResponse({"success": False, "error": "Keine Berechtigung"}, status_code=403)

        writer_versions = [sanitize_post_content(item['ai']) for item in chat_history if 'ai' in item and item['ai']]
        critic_feedback_list = []
        for item in chat_history:
            if 'user' in item and item['user']:
                critic_feedback_list.append({'feedback': item['user'], 'explanation': item.get('explanation', '')})

        from src.database.models import GeneratedPost as GenPost
        new_post = GenPost(
            user_id=emp_profile.id,
            topic_title=topic_title,
            post_content=post_content,
            writer_versions=writer_versions if writer_versions else [post_content],
            critic_feedback=critic_feedback_list,
            iterations=len(writer_versions) if writer_versions else 1,
            status="draft",
            post_type_id=UUID(post_type_id) if post_type_id else None
        )

        saved_post = await db.save_generated_post(new_post)

        return JSONResponse({
            "success": True,
            "post_id": str(saved_post.id),
            "message": "Post erfolgreich gespeichert"
        })

    except Exception as e:
        logger.error(f"Error saving company chat post: {e}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


@user_router.post("/api/company/invite")
async def send_company_invitation(request: Request):
    """Send invitation to a new employee."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if session.account_type != "company" or not session.company_id:
        raise HTTPException(status_code=403, detail="Not a company owner")

    try:
        # CHECK EMPLOYEE LIMIT
        company_id = UUID(session.company_id)
        can_add, error_msg = await db.check_company_employee_limit(company_id)
        if not can_add:
            return {"success": False, "error": error_msg}

        data = await request.json()
        email = data.get("email", "").lower().strip()

        if not email:
            return {"success": False, "error": "E-Mail erforderlich"}

        # Check if user already exists in the system
        existing_user = await db.get_user_by_email(email)
        if existing_user:
            # User exists - check their status
            if existing_user.company_id and str(existing_user.company_id) == session.company_id:
                return {"success": False, "error": "Benutzer ist bereits Mitarbeiter in deinem Unternehmen"}
            elif existing_user.company_id:
                return {"success": False, "error": "Diese E-Mail ist bereits bei einem anderen Unternehmen registriert"}
            else:
                return {"success": False, "error": "Diese E-Mail ist bereits als Ghostwriter-Account registriert"}

        # Check if email already has pending invitation
        existing = await db.get_invitations_by_email(email)
        for inv in existing:
            inv_status = inv.status.value if hasattr(inv.status, 'value') else inv.status
            if inv_status == "pending" and str(inv.company_id) == session.company_id:
                return {"success": False, "error": "Einladung bereits gesendet"}

        # Create invitation
        from src.database.models import Invitation
        invitation = Invitation(
            email=email,
            token=generate_invitation_token(),
            expires_at=get_invitation_expiry(),
            company_id=UUID(session.company_id),
            invited_by_user_id=UUID(session.user_id)
        )
        created_invitation = await db.create_invitation(invitation)

        # Send invitation email
        from src.services.email_service import send_invitation_email
        base_url = str(request.base_url).rstrip('/')
        email_sent = send_invitation_email(
            to_email=email,
            company_name=session.company_name or "Unternehmen",
            inviter_name=session.linkedin_name or session.email,
            token=created_invitation.token,
            base_url=base_url
        )

        return {"success": True, "email_sent": email_sent}

    except Exception as e:
        logger.exception(f"Failed to send invitation: {e}")
        return {"success": False, "error": str(e)}


@user_router.delete("/api/company/invitations/{invitation_id}")
async def cancel_invitation(request: Request, invitation_id: str):
    """Cancel a pending invitation."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if session.account_type != "company" or not session.company_id:
        raise HTTPException(status_code=403, detail="Not a company owner")

    try:
        invitation = await db.get_invitation(UUID(invitation_id))
        if not invitation or str(invitation.company_id) != session.company_id:
            return {"success": False, "error": "Einladung nicht gefunden"}

        await db.update_invitation(UUID(invitation_id), {"status": "cancelled"})
        return {"success": True}

    except Exception as e:
        logger.exception(f"Failed to cancel invitation: {e}")
        return {"success": False, "error": str(e)}


@user_router.delete("/api/company/employees/{user_id}")
async def remove_employee(request: Request, user_id: str):
    """Remove an employee from the company - deletes user completely."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if session.account_type != "company" or not session.company_id:
        raise HTTPException(status_code=403, detail="Not a company owner")

    try:
        user = await db.get_user(UUID(user_id))
        if not user or str(user.company_id) != session.company_id:
            return {"success": False, "error": "Mitarbeiter nicht gefunden"}

        # Store user info before deletion for email
        employee_email = user.email
        employee_name = user.display_name or user.linkedin_name or user.email
        company_name = session.company_name or "Unternehmen"

        # Completely delete user and all related data
        await db.delete_user_completely(UUID(user_id))

        # Send notification email
        from src.services.email_service import send_employee_removal_email
        email_sent = send_employee_removal_email(
            to_email=employee_email,
            employee_name=employee_name,
            company_name=company_name
        )

        logger.info(f"Removed employee {user_id} from company {session.company_id}, email_sent={email_sent}")
        return {"success": True, "email_sent": email_sent}

    except Exception as e:
        logger.exception(f"Failed to remove employee: {e}")
        return {"success": False, "error": str(e)}


# ==================== ONBOARDING API ENDPOINTS ====================

@user_router.post("/api/onboarding/scrape-posts")
async def api_scrape_posts(request: Request):
    """Scrape posts for onboarding."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    if not session.user_id:
        return {"success": False, "error": "User not found"}

    try:
        data = await request.json()
        user_id = UUID(data.get("user_id", session.user_id))
        profile = await db.get_profile(user_id)

        if not profile:
            return {"success": False, "error": "User profile not found"}

        from src.scraper import scraper
        from src.database.models import LinkedInPost

        raw_posts = await scraper.scrape_posts(profile.linkedin_url, limit=50)
        parsed_posts = scraper.parse_posts_data(raw_posts)

        linkedin_posts = []
        for post_data in parsed_posts:
            post = LinkedInPost(user_id=user_id, **post_data)
            linkedin_posts.append(post)

        if linkedin_posts:
            await db.save_linkedin_posts(linkedin_posts)

        return {"success": True, "posts_count": len(linkedin_posts)}

    except Exception as e:
        logger.exception(f"Failed to scrape posts: {e}")
        return {"success": False, "error": str(e)}


@user_router.post("/api/onboarding/add-manual-posts")
async def api_add_manual_posts(request: Request):
    """Add manual example posts."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        data = await request.json()
        user_id = UUID(data.get("user_id", session.user_id))
        posts_data = data.get("posts", [])

        from uuid import uuid4
        from datetime import datetime
        from src.database.models import LinkedInPost
        posts = []
        for p in posts_data:
            post = LinkedInPost(
                user_id=user_id,
                post_text=p.get("post_text", ""),
                post_url=f"manual://{uuid4()}",
                post_date=datetime.now(timezone.utc),
                classification_method="manual"
            )
            posts.append(post)

        if posts:
            await db.save_linkedin_posts(posts)

        return {"success": True, "count": len(posts)}

    except Exception as e:
        logger.exception(f"Failed to add manual posts: {e}")
        return {"success": False, "error": str(e)}


@user_router.delete("/api/onboarding/remove-manual-post/{post_id}")
async def api_remove_manual_post(request: Request, post_id: str):
    """Remove a manual example post."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        await db.delete_linkedin_post(UUID(post_id))
        return {"success": True}
    except Exception as e:
        logger.exception(f"Failed to remove manual post: {e}")
        return {"success": False, "error": str(e)}


@user_router.post("/api/onboarding/add-reference")
async def api_add_reference_profile(request: Request):
    """Add a reference profile for scraping."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        data = await request.json()
        user_id = UUID(data.get("user_id", session.user_id))
        linkedin_url = data.get("linkedin_url", "")

        from src.database.models import ReferenceProfile
        profile = ReferenceProfile(
            user_id=user_id,
            linkedin_url=linkedin_url
        )
        await db.create_reference_profile(profile)

        return {"success": True}

    except Exception as e:
        logger.exception(f"Failed to add reference profile: {e}")
        return {"success": False, "error": str(e)}


@user_router.delete("/api/onboarding/remove-reference/{profile_id}")
async def api_remove_reference_profile(request: Request, profile_id: str):
    """Remove a reference profile."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        await db.delete_reference_profile(UUID(profile_id))
        return {"success": True}
    except Exception as e:
        logger.exception(f"Failed to remove reference profile: {e}")
        return {"success": False, "error": str(e)}


@user_router.post("/api/onboarding/classify-posts")
async def api_classify_posts(request: Request):
    """Run automatic post classification."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        data = await request.json()
        user_id = UUID(data.get("user_id", session.user_id))

        classified_count = await orchestrator.classify_posts(user_id)

        return {"success": True, "classified_count": classified_count}

    except Exception as e:
        logger.exception(f"Failed to classify posts: {e}")
        return {"success": False, "error": str(e)}


@user_router.post("/api/onboarding/categorize-post")
async def api_categorize_single_post(request: Request):
    """Manually categorize a single post."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        data = await request.json()
        post_id = UUID(data.get("post_id"))
        post_type_id = UUID(data.get("post_type_id"))

        await db.update_post_classification(
            post_id=post_id,
            post_type_id=post_type_id,
            classification_method="manual",
            classification_confidence=1.0
        )

        return {"success": True}

    except Exception as e:
        logger.exception(f"Failed to categorize post: {e}")
        return {"success": False, "error": str(e)}


# ==================== CALENDAR / SCHEDULING ENDPOINTS ====================

@user_router.get("/company/calendar", response_class=HTMLResponse)
async def company_calendar_page(request: Request, month: int = None, year: int = None, view: str = "month", week_start: str = None):
    """Company posting calendar page."""
    from datetime import date, datetime, timedelta
    import calendar

    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type != "company" or not session.company_id:
        return RedirectResponse(url="/", status_code=302)

    company_id = UUID(session.company_id)

    # Determine current month/year
    today = date.today()
    current_month = month or today.month
    current_year = year or today.year

    # Calculate prev/next month
    if current_month == 1:
        prev_month, prev_year = 12, current_year - 1
    else:
        prev_month, prev_year = current_month - 1, current_year

    if current_month == 12:
        next_month, next_year = 1, current_year + 1
    else:
        next_month, next_year = current_month + 1, current_year

    # Get month name in German
    month_names = ["Januar", "Februar", "Marz", "April", "Mai", "Juni",
                   "Juli", "August", "September", "Oktober", "November", "Dezember"]
    month_name = month_names[current_month - 1]

    # Get all posts for the company (already enriched with employee info - single optimized query)
    all_posts_raw = await db.get_scheduled_posts_for_company(company_id)

    # Filter out employees who have disabled calendar visibility
    all_posts = []
    hidden_user_ids = set()
    can_schedule_user_ids = set()
    fetched_perms_uids = set()
    for post in all_posts_raw:
        uid = post.get("user_id") or post.get("employee_user_id")
        if uid and uid not in fetched_perms_uids and uid not in hidden_user_ids:
            fetched_perms_uids.add(uid)
            try:
                perms = await get_employee_permissions_or_default(UUID(uid), company_id)
                if not perms.get("can_see_in_calendar", True):
                    hidden_user_ids.add(uid)
                    continue
                if perms.get("can_schedule_posts", True):
                    can_schedule_user_ids.add(uid)
            except Exception:
                can_schedule_user_ids.add(uid)  # default allow
        if uid in hidden_user_ids:
            continue
        all_posts.append(post)

    # Build employee list from posts (no extra queries needed)
    employee_map = {}
    for post in all_posts:
        user_id = str(post.get("user_id", ""))
        if user_id and user_id not in employee_map:
            employee_map[user_id] = {
                "user_id": user_id,
                "name": post.get("employee_name", "Unbekannt"),
            }
    employee_customers = list(employee_map.values())

    # Create calendar structure
    cal = calendar.Calendar(firstweekday=0)  # Monday first
    month_days = cal.monthdayscalendar(current_year, current_month)

    # Build posts by date
    posts_by_date = {}
    unscheduled_posts = []

    for idx, post in enumerate(all_posts):
        user_id = str(post.get("user_id", ""))
        employee_index = list(employee_map.keys()).index(user_id) if user_id in employee_map else 0

        # Parse created_at to datetime if it's a string
        created_at = post.get("created_at")
        if isinstance(created_at, str):
            try:
                created_at = datetime.fromisoformat(created_at.replace("Z", "+00:00"))
            except (ValueError, TypeError):
                created_at = None

        post_data = {
            "id": str(post.get("id")),
            "topic_title": post.get("topic_title", "Ohne Titel"),
            "post_content": post.get("post_content", ""),
            "status": post.get("status", "draft"),
            "employee_name": post.get("employee_name", "Unbekannt"),
            "employee_index": employee_index,
            "created_at": created_at
        }

        scheduled_at = post.get("scheduled_at")
        if scheduled_at and post.get("status") in ("scheduled", "published"):
            if isinstance(scheduled_at, str):
                scheduled_dt = datetime.fromisoformat(scheduled_at.replace("Z", "+00:00"))
            else:
                scheduled_dt = scheduled_at

            date_key = scheduled_dt.strftime("%Y-%m-%d")
            post_data["time"] = scheduled_dt.strftime("%H:%M")

            if date_key not in posts_by_date:
                posts_by_date[date_key] = []
            posts_by_date[date_key].append(post_data)
        elif post.get("status") == "ready":
            # Unscheduled but ready for scheduling
            uid = str(post.get("user_id", ""))
            post_data["can_schedule"] = uid in can_schedule_user_ids
            unscheduled_posts.append(post_data)

    # Build calendar weeks
    calendar_weeks = []

    if view == "week":
        # Week view: show a single week (Mon-Sun)
        if week_start:
            try:
                ws_date = date.fromisoformat(week_start)
            except ValueError:
                ws_date = today - timedelta(days=today.weekday())
        else:
            ws_date = today - timedelta(days=today.weekday())

        week_data = []
        for i in range(7):
            d = ws_date + timedelta(days=i)
            date_str = d.isoformat()
            week_data.append({
                "day": d.day,
                "date": date_str,
                "other_month": d.month != current_month,
                "is_today": d == today,
                "posts": posts_by_date.get(date_str, []),
                "weekday_name": ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"][i],
                "full_date": f"{d.day}. {month_names[d.month - 1]}"
            })
        calendar_weeks.append(week_data)

        prev_ws = ws_date - timedelta(weeks=1)
        next_ws = ws_date + timedelta(weeks=1)
        ws_end = ws_date + timedelta(days=6)

        # Week label e.g. "3. - 9. Feb 2026"
        if ws_date.month == ws_end.month:
            week_label = f"{ws_date.day}. - {ws_end.day}. {month_names[ws_date.month - 1]} {ws_date.year}"
        else:
            week_label = f"{ws_date.day}. {month_names[ws_date.month - 1]} - {ws_end.day}. {month_names[ws_end.month - 1]} {ws_end.year}"
    else:
        # Month view
        for week in month_days:
            week_data = []
            for day in week:
                if day == 0:
                    week_data.append({
                        "day": "",
                        "date": "",
                        "other_month": True,
                        "is_today": False,
                        "posts": []
                    })
                else:
                    date_str = f"{current_year}-{current_month:02d}-{day:02d}"
                    is_today = (day == today.day and current_month == today.month and current_year == today.year)
                    week_data.append({
                        "day": day,
                        "date": date_str,
                        "other_month": False,
                        "is_today": is_today,
                        "posts": posts_by_date.get(date_str, [])
                    })
            calendar_weeks.append(week_data)

        week_label = None
        prev_ws = None
        next_ws = None

    return templates.TemplateResponse("company_calendar.html", {
        "request": request,
        "page": "calendar",
        "session": session,
        "month": current_month,
        "year": current_year,
        "month_name": month_name,
        "prev_month": prev_month,
        "prev_year": prev_year,
        "next_month": next_month,
        "next_year": next_year,
        "current_month": today.month,
        "current_year": today.year,
        "employees": employee_customers,
        "calendar_weeks": calendar_weeks,
        "unscheduled_posts": unscheduled_posts,
        "view": view,
        "week_label": week_label,
        "week_start": prev_ws.isoformat() if prev_ws else None,
        "prev_week_start": prev_ws.isoformat() if prev_ws else None,
        "next_week_start": next_ws.isoformat() if next_ws else None
    })


@user_router.get("/calendar", response_class=HTMLResponse)
async def employee_calendar_page(request: Request, month: int = None, year: int = None, view: str = "month", week_start: str = None):
    """Employee/ghostwriter personal posting calendar page."""
    from datetime import date, datetime, timedelta
    import calendar

    session = require_user_session(request)
    if not session:
        return RedirectResponse(url="/login", status_code=302)

    if session.account_type == "company":
        return RedirectResponse(url="/company/calendar", status_code=302)

    user_id = UUID(session.user_id)
    today = date.today()
    current_month = month or today.month
    current_year = year or today.year

    if current_month == 1:
        prev_month, prev_year = 12, current_year - 1
    else:
        prev_month, prev_year = current_month - 1, current_year

    if current_month == 12:
        next_month, next_year = 1, current_year + 1
    else:
        next_month, next_year = current_month + 1, current_year

    month_names = ["Januar", "Februar", "März", "April", "Mai", "Juni",
                   "Juli", "August", "September", "Oktober", "November", "Dezember"]
    month_name = month_names[current_month - 1]

    # Get all own posts that are in relevant statuses
    all_posts = await db.get_scheduled_posts_for_user(user_id)

    # Build posts by date
    posts_by_date = {}
    unscheduled_posts = []

    for post in all_posts:
        post_data = {
            "id": str(post.id),
            "topic_title": post.topic_title or "Ohne Titel",
            "post_content": post.post_content,
            "status": post.status,
        }

        if post.scheduled_at and post.status in ("scheduled", "published"):
            scheduled_dt = post.scheduled_at
            if not scheduled_dt.tzinfo:
                scheduled_dt = scheduled_dt.replace(tzinfo=timezone.utc)
            date_key = scheduled_dt.strftime("%Y-%m-%d")
            post_data["time"] = scheduled_dt.strftime("%H:%M")
            if date_key not in posts_by_date:
                posts_by_date[date_key] = []
            posts_by_date[date_key].append(post_data)
        elif post.status in ("ready", "approved"):
            unscheduled_posts.append(post_data)

    cal = calendar.Calendar(firstweekday=0)
    month_days = cal.monthdayscalendar(current_year, current_month)
    calendar_weeks = []
    week_label = None
    prev_ws = None
    next_ws = None

    if view == "week":
        if week_start:
            try:
                ws_date = date.fromisoformat(week_start)
            except ValueError:
                ws_date = today - timedelta(days=today.weekday())
        else:
            ws_date = today - timedelta(days=today.weekday())

        week_data = []
        for i in range(7):
            d = ws_date + timedelta(days=i)
            date_str = d.isoformat()
            week_data.append({
                "day": d.day,
                "date": date_str,
                "other_month": d.month != current_month,
                "is_today": d == today,
                "posts": posts_by_date.get(date_str, []),
                "weekday_name": ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"][i],
                "full_date": f"{d.day}. {month_names[d.month - 1]}"
            })
        calendar_weeks.append(week_data)

        prev_ws = ws_date - timedelta(weeks=1)
        next_ws = ws_date + timedelta(weeks=1)
        ws_end = ws_date + timedelta(days=6)

        if ws_date.month == ws_end.month:
            week_label = f"{ws_date.day}. - {ws_end.day}. {month_names[ws_date.month - 1]} {ws_date.year}"
        else:
            week_label = f"{ws_date.day}. {month_names[ws_date.month - 1]} - {ws_end.day}. {month_names[ws_end.month - 1]} {ws_end.year}"
    else:
        for week in month_days:
            week_data = []
            for day in week:
                if day == 0:
                    week_data.append({"day": "", "date": "", "other_month": True, "is_today": False, "posts": []})
                else:
                    date_str = f"{current_year}-{current_month:02d}-{day:02d}"
                    is_today = (day == today.day and current_month == today.month and current_year == today.year)
                    week_data.append({
                        "day": day, "date": date_str, "other_month": False,
                        "is_today": is_today, "posts": posts_by_date.get(date_str, [])
                    })
            calendar_weeks.append(week_data)

    avatar_url = await get_user_avatar(session, user_id)

    return templates.TemplateResponse("employee_calendar.html", {
        "request": request,
        "page": "calendar",
        "session": session,
        "avatar_url": avatar_url,
        "month": current_month,
        "year": current_year,
        "month_name": month_name,
        "prev_month": prev_month,
        "prev_year": prev_year,
        "next_month": next_month,
        "next_year": next_year,
        "current_month": today.month,
        "current_year": today.year,
        "calendar_weeks": calendar_weeks,
        "unscheduled_posts": unscheduled_posts,
        "view": view,
        "week_label": week_label,
        "prev_week_start": prev_ws.isoformat() if prev_ws else None,
        "next_week_start": next_ws.isoformat() if next_ws else None,
    })


@user_router.get("/api/posts/{post_id}")
async def get_post_api(request: Request, post_id: str):
    """Get a single post as JSON."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Verify access (owner or company owner)
        is_owner = session.user_id and str(post.user_id) == session.user_id
        is_company_owner = False

        if not is_owner and session.account_type == "company" and session.company_id:
            profile = await db.get_profile(post.user_id)
            if profile and profile.company_id and str(profile.company_id) == session.company_id:
                is_company_owner = True

        if not is_owner and not is_company_owner:
            raise HTTPException(status_code=403, detail="Not authorized")

        return {
            "id": str(post.id),
            "topic_title": post.topic_title,
            "post_content": post.post_content,
            "status": post.status,
            "scheduled_at": post.scheduled_at.isoformat() if post.scheduled_at else None,
            "created_at": post.created_at.isoformat() if post.created_at else None
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to get post: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/posts/{post_id}/schedule")
async def schedule_post(request: Request, post_id: str, scheduled_at: str = Form(...)):
    """Schedule a post for publishing."""
    from datetime import datetime

    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Determine authorization
        is_post_owner = str(post.user_id) == session.user_id
        is_company_scheduling = session.account_type == "company" and session.company_id

        if is_post_owner:
            # Post owner can always schedule their own posts
            pass
        elif is_company_scheduling:
            # Company must have can_schedule_posts permission
            profile = await db.get_profile(post.user_id)
            if not profile or not profile.company_id or str(profile.company_id) != session.company_id:
                raise HTTPException(status_code=403, detail="Not authorized")
            perms = await get_employee_permissions_or_default(post.user_id, UUID(session.company_id))
            if not perms.get("can_schedule_posts", True):
                raise HTTPException(status_code=403, detail="Keine Berechtigung zum Einplanen von Posts")
        else:
            raise HTTPException(status_code=403, detail="Not authorized to schedule posts")

        # Only ready posts can be scheduled
        if post.status not in ["ready", "scheduled"]:
            raise HTTPException(status_code=400, detail="Only ready (approved by customer) posts can be scheduled")

        # Parse scheduled_at
        try:
            scheduled_datetime = datetime.fromisoformat(scheduled_at.replace("Z", "+00:00"))
        except ValueError:
            raise HTTPException(status_code=400, detail="Invalid datetime format")

        # Schedule the post
        updated_post = await db.schedule_post(
            post_id=UUID(post_id),
            scheduled_at=scheduled_datetime,
            scheduled_by_user_id=UUID(session.user_id)
        )

        return {
            "success": True,
            "scheduled_at": updated_post.scheduled_at.isoformat() if updated_post.scheduled_at else None
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to schedule post: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.post("/api/posts/{post_id}/unschedule")
async def unschedule_post(request: Request, post_id: str):
    """Remove scheduling from a post."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Determine authorization
        is_post_owner = str(post.user_id) == session.user_id
        is_company_scheduling = session.account_type == "company" and session.company_id

        if is_post_owner:
            # Post owner can always unschedule their own posts
            pass
        elif is_company_scheduling:
            profile = await db.get_profile(post.user_id)
            if not profile or not profile.company_id or str(profile.company_id) != session.company_id:
                raise HTTPException(status_code=403, detail="Not authorized")
            perms = await get_employee_permissions_or_default(post.user_id, UUID(session.company_id))
            if not perms.get("can_schedule_posts", True):
                raise HTTPException(status_code=403, detail="Keine Berechtigung zum Einplanen von Posts")
        else:
            raise HTTPException(status_code=403, detail="Not authorized to unschedule posts")

        # Unschedule the post
        updated_post = await db.unschedule_post(UUID(post_id))

        return {
            "success": True,
            "status": updated_post.status
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to unschedule post: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== POST IMAGE UPLOAD ====================

@user_router.post("/api/posts/{post_id}/image")
async def upload_post_image(request: Request, post_id: str):
    """DEPRECATED: Upload or replace an image for a post.

    Use /api/posts/{post_id}/media instead. This endpoint is kept for backward compatibility.
    """
    # Delegate to new media upload endpoint
    result = await upload_post_media(request, post_id)

    # Return legacy format for compatibility
    if result.get("success") and result.get("media_item"):
        return {"success": True, "image_url": result["media_item"]["url"]}

    return result


@user_router.delete("/api/posts/{post_id}/image")
async def delete_post_image(request: Request, post_id: str):
    """Remove the image from a post."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Check authorization: owner or company owner
        is_owner = session.user_id and str(post.user_id) == session.user_id
        is_company_owner = False
        if not is_owner and session.account_type == "company" and session.company_id:
            profile = await db.get_profile(post.user_id)
            if profile and profile.company_id and str(profile.company_id) == session.company_id:
                is_company_owner = True
        if not is_owner and not is_company_owner:
            raise HTTPException(status_code=403, detail="Not authorized")

        # Delete from storage
        if post.image_url:
            try:
                await storage.delete_image(post.image_url)
            except Exception as e:
                logger.warning(f"Failed to delete image from storage: {e}")

        # Clear image_url on post
        await db.update_generated_post(UUID(post_id), {"image_url": None})

        return {"success": True}

    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to delete post image: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== POST MEDIA UPLOAD (MULTI-MEDIA) ====================

@user_router.post("/api/posts/{post_id}/media")
async def upload_post_media(request: Request, post_id: str):
    """Upload a media item (image or video). Max 3 items per post."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Check authorization: owner or company owner
        is_owner = session.user_id and str(post.user_id) == session.user_id
        is_company_owner = False
        if not is_owner and session.account_type == "company" and session.company_id:
            profile = await db.get_profile(post.user_id)
            if profile and profile.company_id and str(profile.company_id) == session.company_id:
                is_company_owner = True
        if not is_owner and not is_company_owner:
            raise HTTPException(status_code=403, detail="Not authorized")

        # Get current media items (convert to dicts with JSON-serializable datetime)
        media_items = [
            item.model_dump(mode='json') if hasattr(item, 'model_dump') else (item.dict() if hasattr(item, 'dict') else item)
            for item in (post.media_items or [])
        ]

        # Validate: Max 3 items
        if len(media_items) >= 3:
            raise HTTPException(status_code=400, detail="Maximal 3 Medien erlaubt")

        # Read file from form data
        form = await request.form()
        file = form.get("file") or form.get("image")  # Support both 'file' and 'image' keys
        if not file or not hasattr(file, "read"):
            raise HTTPException(status_code=400, detail="No file provided")

        file_content = await file.read()
        content_type = file.content_type or "application/octet-stream"

        # Validate media type consistency (no mixing)
        is_video = content_type.startswith("video/")
        has_videos = any(item.get("type") == "video" for item in media_items)
        has_images = any(item.get("type") == "image" for item in media_items)

        if (is_video and has_images) or (not is_video and has_videos):
            raise HTTPException(status_code=400, detail="Kann nicht Bilder und Videos mischen")

        # Only allow 1 video max
        if is_video and len(media_items) > 0:
            raise HTTPException(status_code=400, detail="Nur 1 Video pro Post erlaubt")

        # Upload to storage
        media_url = await storage.upload_media(
            file_content=file_content,
            content_type=content_type,
            user_id=str(post.user_id),
        )

        # Add to array
        new_item = {
            "type": "video" if is_video else "image",
            "url": media_url,
            "order": len(media_items),
            "content_type": content_type,
            "uploaded_at": datetime.now(timezone.utc).isoformat(),
            "metadata": None
        }
        media_items.append(new_item)

        # Update DB
        await db.update_generated_post(UUID(post_id), {"media_items": media_items})

        # Also update image_url for backward compatibility (first image)
        if new_item["type"] == "image" and len([i for i in media_items if i["type"] == "image"]) == 1:
            await db.update_generated_post(UUID(post_id), {"image_url": media_url})

        return {"success": True, "media_item": new_item, "media_items": media_items}

    except HTTPException:
        raise
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.exception(f"Failed to upload post media: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.delete("/api/posts/{post_id}/media/{media_index}")
async def delete_post_media(request: Request, post_id: str, media_index: int):
    """Delete a specific media item by index."""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Check authorization: owner or company owner
        is_owner = session.user_id and str(post.user_id) == session.user_id
        is_company_owner = False
        if not is_owner and session.account_type == "company" and session.company_id:
            profile = await db.get_profile(post.user_id)
            if profile and profile.company_id and str(profile.company_id) == session.company_id:
                is_company_owner = True
        if not is_owner and not is_company_owner:
            raise HTTPException(status_code=403, detail="Not authorized")

        # Get current media items (convert to dicts with JSON-serializable datetime)
        media_items = [
            item.model_dump(mode='json') if hasattr(item, 'model_dump') else (item.dict() if hasattr(item, 'dict') else item)
            for item in (post.media_items or [])
        ]

        if media_index < 0 or media_index >= len(media_items):
            raise HTTPException(status_code=404, detail="Media item nicht gefunden")

        # Delete from storage
        item_to_delete = media_items[media_index]
        try:
            await storage.delete_image(item_to_delete["url"])
        except Exception as e:
            logger.warning(f"Failed to delete media from storage: {e}")

        # Remove and re-index
        media_items.pop(media_index)
        for i, item in enumerate(media_items):
            item["order"] = i

        # Update DB
        await db.update_generated_post(UUID(post_id), {"media_items": media_items})

        # Update image_url for backward compatibility
        first_image = next((item for item in media_items if item["type"] == "image"), None)
        await db.update_generated_post(UUID(post_id), {"image_url": first_image["url"] if first_image else None})

        return {"success": True, "media_items": media_items}

    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to delete post media: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@user_router.put("/api/posts/{post_id}/media/reorder")
async def reorder_post_media(request: Request, post_id: str):
    """Reorder media items. Expects JSON: {"order": [2, 0, 1]}"""
    session = require_user_session(request)
    if not session:
        raise HTTPException(status_code=401, detail="Not authenticated")

    try:
        post = await db.get_generated_post(UUID(post_id))
        if not post:
            raise HTTPException(status_code=404, detail="Post not found")

        # Check authorization: owner or company owner
        is_owner = session.user_id and str(post.user_id) == session.user_id
        is_company_owner = False
        if not is_owner and session.account_type == "company" and session.company_id:
            profile = await db.get_profile(post.user_id)
            if profile and profile.company_id and str(profile.company_id) == session.company_id:
                is_company_owner = True
        if not is_owner and not is_company_owner:
            raise HTTPException(status_code=403, detail="Not authorized")

        # Get current media items (convert to dicts with JSON-serializable datetime)
        media_items = [
            item.model_dump(mode='json') if hasattr(item, 'model_dump') else (item.dict() if hasattr(item, 'dict') else item)
            for item in (post.media_items or [])
        ]

        # Parse request body
        body = await request.json()
        new_order = body.get("order", [])

        # Validate order array
        if len(new_order) != len(media_items) or set(new_order) != set(range(len(media_items))):
            raise HTTPException(status_code=400, detail="Invalid order indices")

        # Reorder
        reordered = [media_items[i] for i in new_order]
        for i, item in enumerate(reordered):
            item["order"] = i

        # Update DB
        await db.update_generated_post(UUID(post_id), {"media_items": reordered})

        return {"success": True, "media_items": reordered}

    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Failed to reorder post media: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== IMAGE PROXY FOR HTTPS ====================

@user_router.get("/proxy/image/{bucket}/{path:path}")
async def proxy_supabase_image(bucket: str, path: str):
    """
    Proxy Supabase storage images via HTTPS to avoid mixed content warnings.

    This allows HTTPS pages to load images from HTTP Supabase storage.
    """
    import httpx
    from fastapi.responses import Response

    try:
        # Build the Supabase storage URL
        storage_url = settings.supabase_url.replace("https://", "http://").replace("http://", "http://")
        image_url = f"{storage_url}/storage/v1/object/public/{bucket}/{path}"

        # Fetch the image from Supabase
        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.get(image_url)

            if response.status_code != 200:
                raise HTTPException(status_code=404, detail="Image not found")

            # Return the image with proper headers
            return Response(
                content=response.content,
                media_type=response.headers.get("content-type", "image/jpeg"),
                headers={
                    "Cache-Control": "public, max-age=31536000",
                    "Access-Control-Allow-Origin": "*"
                }
            )

    except httpx.TimeoutException:
        raise HTTPException(status_code=504, detail="Image fetch timeout")
    except Exception as e:
        logger.error(f"Failed to proxy image {bucket}/{path}: {e}")
        raise HTTPException(status_code=500, detail="Failed to load image")


# ==================== TELEGRAM BOT ====================

if settings.telegram_enabled:
    import secrets as _secrets
    from src.services.telegram_service import telegram_service as _telegram_service

    @user_router.get("/settings/telegram/start")
    async def telegram_start_link(request: Request):
        """Generate a one-time Telegram linking token and return the bot link."""
        session = require_user_session(request)
        if not session:
            raise HTTPException(status_code=401, detail="Not authenticated")

        from src.services.redis_client import get_redis
        token = _secrets.token_urlsafe(32)
        try:
            redis = await get_redis()
            await redis.setex(f"telegram_link:{token}", 600, session.user_id)
        except Exception as e:
            logger.error(f"Failed to store telegram link token: {e}")
            raise HTTPException(status_code=500, detail="Failed to generate link")

        return JSONResponse({
            "bot_username": settings.telegram_bot_username,
            "token": token
        })

    @user_router.post("/api/telegram/webhook")
    async def telegram_webhook(request: Request):
        """Receive Telegram webhook updates."""
        secret = request.headers.get("X-Telegram-Bot-Api-Secret-Token", "")
        if secret != settings.telegram_webhook_secret:
            raise HTTPException(status_code=403, detail="Invalid secret")

        try:
            update = await request.json()
            if _telegram_service:
                await _telegram_service.handle_update(update, db)
        except Exception as e:
            logger.error(f"Telegram webhook error: {e}")
        # Always return 200 — Telegram requires it
        return {"ok": True}

    @user_router.post("/api/settings/telegram/disconnect")
    async def telegram_disconnect(request: Request):
        """Disconnect Telegram account."""
        session = require_user_session(request)
        if not session:
            raise HTTPException(status_code=401, detail="Not authenticated")

        await db.delete_telegram_account(UUID(session.user_id))
        return JSONResponse({"success": True})


# ==================== MICROSOFT TEAMS BOT ====================

if settings.teams_enabled:
    import secrets as _secrets_teams
    from src.services.teams_service import teams_service as _teams_service

    @user_router.get("/settings/teams/start")
    async def teams_start_link(request: Request):
        """Generate a one-time Teams linking token and return the deep link."""
        session = require_user_session(request)
        if not session:
            raise HTTPException(status_code=401, detail="Not authenticated")

        from src.services.redis_client import get_redis
        token = _secrets_teams.token_urlsafe(32)
        try:
            redis = await get_redis()
            await redis.setex(f"teams_link:{token}", 600, session.user_id)
        except Exception as e:
            logger.error(f"Failed to store teams link token: {e}")
            raise HTTPException(status_code=500, detail="Failed to generate link")

        deep_link = (
            f"https://teams.microsoft.com/l/chat/0/0"
            f"?users=28:{settings.microsoft_app_id}&message=link:{token}"
        )
        return JSONResponse({"deep_link": deep_link, "token": token})

    async def _handle_teams_link(activity: dict, link_token: str) -> None:
        """Handle account linking when user sends 'link:{token}' to the bot."""
        from src.services.redis_client import get_redis
        from src.database.models import TeamsAccount

        try:
            redis = await get_redis()
            link_key = f"teams_link:{link_token}"
            raw_user_id = await redis.get(link_key)
            if not raw_user_id:
                logger.warning(f"Teams link token not found or expired: {link_token[:8]}…")
                if _teams_service:
                    conv_id = activity.get("conversation", {}).get("id", "")
                    service_url = activity.get("serviceUrl", "")
                    if conv_id and service_url:
                        from src.database.models import TeamsAccount as _TA
                        dummy = _TA(
                            user_id=UUID("00000000-0000-0000-0000-000000000000"),
                            teams_service_url=service_url,
                            teams_conversation_id=conv_id,
                        )
                        await _teams_service.send_text_message(
                            dummy,
                            "❌ Dieser Link ist ungültig oder abgelaufen. Bitte erstelle einen neuen Link in der App.",
                        )
                return

            user_id_str = raw_user_id.decode() if isinstance(raw_user_id, bytes) else raw_user_id
            await redis.delete(link_key)
        except Exception as e:
            logger.error(f"Failed to look up teams link token: {e}")
            return

        # Extract conversation reference from incoming activity
        service_url = activity.get("serviceUrl", "")
        conversation_id = activity.get("conversation", {}).get("id", "")
        teams_user_id = activity.get("from", {}).get("id", "")
        tenant_id = activity.get("channelData", {}).get("tenant", {}).get("id")

        if not service_url or not conversation_id:
            logger.error("Teams link activity missing serviceUrl or conversation.id")
            return

        account = TeamsAccount(
            user_id=UUID(user_id_str),
            teams_user_id=teams_user_id or None,
            teams_tenant_id=tenant_id,
            teams_service_url=service_url,
            teams_conversation_id=conversation_id,
            is_active=True,
        )
        await db.save_teams_account(account)

        if _teams_service:
            await _teams_service.send_text_message(
                account,
                "✅ Dein Teams-Konto ist jetzt verbunden! Du erhältst ab sofort Freigabe-Anfragen direkt hier.",
            )

    async def _handle_teams_approval(activity: dict, action: str, token: str) -> None:
        """Handle approve/reject invoke from an Adaptive Card button."""
        from src.services.email_service import validate_token, mark_all_post_tokens_used

        token_data = await validate_token(token)
        if not token_data:
            logger.warning(f"Teams approval: invalid or used token {token[:8]}…")
            return

        post_id = UUID(token_data["post_id"])
        new_status = "ready" if action == "approve" else "draft"
        await db.update_generated_post(post_id, {"status": new_status})
        await db.mark_all_post_tokens_used(post_id)

        logger.info(f"Teams approval handled: post={post_id} action={action} status={new_status}")

    @user_router.post("/api/teams/webhook")
    async def teams_webhook(request: Request):
        """Receive Microsoft Teams bot activities."""
        # Validate incoming JWT
        auth_header = request.headers.get("Authorization", "")
        if _teams_service and not await _teams_service.validate_incoming_token(auth_header):
            raise HTTPException(status_code=403, detail="Invalid Teams JWT")

        try:
            activity = await request.json()
        except Exception:
            raise HTTPException(status_code=400, detail="Invalid JSON")

        activity_type = activity.get("type", "")

        if activity_type == "message":
            text = (activity.get("text") or "").strip()
            if text.startswith("link:"):
                link_token = text[5:].strip()
                await _handle_teams_link(activity, link_token)

        elif activity_type == "invoke" and activity.get("name") == "adaptiveCard/action":
            value = activity.get("value", {})
            action = value.get("action", {})
            action_data = action.get("data", {}) if isinstance(action, dict) else {}
            act = action_data.get("action", "")
            token = action_data.get("token", "")
            if act in ("approve", "reject") and token:
                await _handle_teams_approval(activity, act, token)
            # Teams requires a synchronous 200 with statusCode for invoke
            return JSONResponse({"statusCode": 200})

        # conversationUpdate and other types — ignore
        return JSONResponse({"ok": True})

    @user_router.post("/api/settings/teams/disconnect")
    async def teams_disconnect(request: Request):
        """Disconnect Teams account."""
        session = require_user_session(request)
        if not session:
            raise HTTPException(status_code=401, detail="Not authenticated")

        await db.delete_teams_account(UUID(session.user_id))
        return JSONResponse({"success": True})
