"""
API endpoints for LLM-powered naming features.
Used by Trends and Forge tabs in the Hunt page.
"""
from __future__ import annotations

from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_user
from app.database import get_db
from app.models.subscription import Subscription, SubscriptionTier
from app.models.user import User
from app.services.llm_naming import (
    expand_trend_keywords,
    analyze_trend,
    generate_brandable_names,
    generate_similar_names,
)


router = APIRouter(prefix="/naming", tags=["LLM Naming"])


def _tier_level(tier: str) -> int:
    t = (tier or "").lower()
    if t == "tycoon":
        return 3
    if t == "trader":
        return 2
    return 1


async def _get_user_tier(db: AsyncSession, user: User) -> str:
    res = await db.execute(select(Subscription).where(Subscription.user_id == user.id))
    sub = res.scalar_one_or_none()
    if not sub:
        return "scout"
    return sub.tier.value


async def _require_trader_or_above(db: AsyncSession, user: User):
    """Check that user has at least Trader tier."""
    tier = await _get_user_tier(db, user)
    if _tier_level(tier) < 2:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="AI naming features require Trader or Tycoon plan."
        )


# ============================================================================
# TRENDS TAB ENDPOINTS
# ============================================================================

class TrendExpandRequest(BaseModel):
    trend: str = Field(..., min_length=1, max_length=100)
    geo: str = Field(default="US", max_length=5)


class TrendExpandResponse(BaseModel):
    keywords: list[str]
    trend: str


@router.post("/trends/expand", response_model=TrendExpandResponse)
async def expand_trend(
    request: TrendExpandRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """
    Expand a trending topic into related domain-friendly keywords.
    Requires Trader or Tycoon subscription.
    """
    await _require_trader_or_above(db, current_user)
    
    keywords = await expand_trend_keywords(request.trend, request.geo)
    return TrendExpandResponse(keywords=keywords, trend=request.trend)


class TrendAnalyzeRequest(BaseModel):
    trend: str = Field(..., min_length=1, max_length=100)
    geo: str = Field(default="US", max_length=5)


class TrendAnalyzeResponse(BaseModel):
    analysis: str
    trend: str


@router.post("/trends/analyze", response_model=TrendAnalyzeResponse)
async def analyze_trend_endpoint(
    request: TrendAnalyzeRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """
    Get AI analysis of a trending topic for domain investors.
    Requires Trader or Tycoon subscription.
    """
    await _require_trader_or_above(db, current_user)
    
    analysis = await analyze_trend(request.trend, request.geo)
    return TrendAnalyzeResponse(analysis=analysis, trend=request.trend)


# ============================================================================
# FORGE TAB ENDPOINTS
# ============================================================================

class BrandableGenerateRequest(BaseModel):
    concept: str = Field(..., min_length=3, max_length=200)
    style: Optional[str] = Field(default=None, max_length=50)
    count: int = Field(default=15, ge=5, le=30)


class BrandableGenerateResponse(BaseModel):
    names: list[str]
    concept: str


@router.post("/forge/generate", response_model=BrandableGenerateResponse)
async def generate_brandables(
    request: BrandableGenerateRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """
    Generate brandable domain names based on a concept description.
    Requires Trader or Tycoon subscription.
    """
    await _require_trader_or_above(db, current_user)
    
    names = await generate_brandable_names(
        request.concept,
        style=request.style,
        count=request.count
    )
    return BrandableGenerateResponse(names=names, concept=request.concept)


class SimilarNamesRequest(BaseModel):
    brand: str = Field(..., min_length=2, max_length=50)
    count: int = Field(default=12, ge=5, le=20)


class SimilarNamesResponse(BaseModel):
    names: list[str]
    brand: str


@router.post("/forge/similar", response_model=SimilarNamesResponse)
async def generate_similar(
    request: SimilarNamesRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """
    Generate names similar to an existing brand.
    Requires Trader or Tycoon subscription.
    """
    await _require_trader_or_above(db, current_user)
    
    names = await generate_similar_names(request.brand, count=request.count)
    return SimilarNamesResponse(names=names, brand=request.brand)

