# Identity Endpoints for Account Linking (Telegram ↔ Energy Union)
# This file is appended to main.py

import secrets
from datetime import datetime, timedelta
from pydantic import BaseModel
from typing import Optional


# ============================================================================
# IDENTITY & ACCOUNT LINKING
# ============================================================================

class LinkStartRequest(BaseModel):
    account_id: str  # UUID as string
    ttl_minutes: int = 10


class LinkStartResponse(BaseModel):
    link_code: str
    expires_at: datetime


class ResolveResponse(BaseModel):
    account_id: Optional[str] = None
    linked: bool = False
    linked_at: Optional[datetime] = None


@app.post("/identity/link/start", response_model=LinkStartResponse)
async def start_link(request: LinkStartRequest):
    """
    Generate a one-time link code for account linking.
    This is called from Energy Union dashboard when user clicks "Link Telegram".
    """
    try:
        # Generate secure random code
        link_code = secrets.token_urlsafe(16)[:20].upper()
        expires_at = datetime.utcnow() + timedelta(minutes=request.ttl_minutes)
        
        # Store in database
        await db.pool.execute(
            """
            INSERT INTO link_codes (code, account_id, expires_at, generated_via)
            VALUES ($1, $2::uuid, $3, 'api')
            """,
            link_code,
            request.account_id,
            expires_at
        )
        
        logger.info("link_code_generated", account_id=request.account_id, code=link_code[:4] + "***")
        
        return LinkStartResponse(
            link_code=link_code,
            expires_at=expires_at
        )
        
    except Exception as e:
        logger.error("link_code_generation_failed", error=str(e))
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/identity/resolve", response_model=ResolveResponse)
async def resolve_telegram(telegram_user_id: int):
    """
    Resolve Telegram user ID to Energy Union account ID.
    Returns null account_id if not linked.
    """
    try:
        row = await db.pool.fetchrow(
            """
            SELECT account_id, linked_at
            FROM account_links
            WHERE telegram_user_id = $1 AND status = 'active'
            """,
            telegram_user_id
        )
        
        if row:
            return ResolveResponse(
                account_id=str(row['account_id']),
                linked=True,
                linked_at=row['linked_at']
            )
        else:
            return ResolveResponse(linked=False)
            
    except Exception as e:
        logger.error("telegram_resolve_failed", error=str(e))
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/identity/user/{account_id}/timeline")
async def get_user_timeline(
    account_id: str,
    limit: int = Query(default=20, le=100),
    channel: Optional[str] = None
):
    """
    Get user's interaction timeline across all channels.
    Only available for linked accounts.
    """
    try:
        if channel:
            rows = await db.pool.fetch(
                """
                SELECT id, channel, channel_id, event_type, summary, 
                       metadata, importance_score, event_at
                FROM user_timeline
                WHERE account_id = $1::uuid AND channel = $2
                ORDER BY event_at DESC
                LIMIT $3
                """,
                account_id, channel, limit
            )
        else:
            rows = await db.pool.fetch(
                """
                SELECT id, channel, channel_id, event_type, summary, 
                       metadata, importance_score, event_at
                FROM user_timeline
                WHERE account_id = $1::uuid
                ORDER BY event_at DESC
                LIMIT $3
                """,
                account_id, limit
            )
        
        events = []
        for row in rows:
            events.append({
                "id": str(row['id']),
                "channel": row['channel'],
                "channel_id": row['channel_id'],
                "event_type": row['event_type'],
                "summary": row['summary'],
                "metadata": row['metadata'] or {},
                "importance_score": row['importance_score'],
                "event_at": row['event_at'].isoformat()
            })
        
        return {"events": events, "account_id": account_id, "count": len(events)}
        
    except Exception as e:
        logger.error("timeline_fetch_failed", error=str(e), account_id=account_id)
        raise HTTPException(status_code=500, detail=str(e))


@app.post("/identity/timeline/add")
async def add_timeline_event(
    account_id: str,
    channel: str,
    channel_id: str,
    event_type: str,
    summary: str,
    metadata: Optional[dict] = None,
    importance_score: float = 0.5
):
    """
    Add an event to user's timeline.
    Called by Gateway when processing messages from linked accounts.
    """
    try:
        event_id = await db.pool.fetchval(
            """
            SELECT add_timeline_event($1::uuid, $2, $3, $4, $5, $6::jsonb, $7)
            """,
            account_id, channel, channel_id, event_type, 
            summary, metadata or {}, importance_score
        )
        
        return {"event_id": str(event_id), "success": True}
        
    except Exception as e:
        logger.error("timeline_add_failed", error=str(e))
        raise HTTPException(status_code=500, detail=str(e))
