"""
AI SEO Tools FastAPI Router

This module provides FastAPI endpoints for all AI SEO tools migrated from ToBeMigrated/ai_seo_tools.
Includes intelligent logging, exception handling, and structured responses.
"""

from fastapi import APIRouter, HTTPException, Depends, BackgroundTasks, UploadFile, File
from fastapi.responses import JSONResponse
from pydantic import BaseModel, HttpUrl, Field, validator
from typing import Dict, Any, List, Optional, Union
from datetime import datetime
import json
import traceback
from loguru import logger
import os
import tempfile
import asyncio

# Import services
from services.llm_providers.main_text_generation import llm_text_gen
from services.seo_tools.meta_description_service import MetaDescriptionService
from services.seo_tools.pagespeed_service import PageSpeedService
from services.seo_tools.sitemap_service import SitemapService
from services.seo_tools.image_alt_service import ImageAltService
from services.seo_tools.opengraph_service import OpenGraphService
from services.seo_tools.on_page_seo_service import OnPageSEOService
from services.seo_tools.technical_seo_service import TechnicalSEOService
from services.seo_tools.enterprise_seo_service import EnterpriseSEOService
from services.seo_tools.content_strategy_service import ContentStrategyService
from middleware.logging_middleware import log_api_call, save_to_file

router = APIRouter(prefix="/api/seo", tags=["AI SEO Tools"])

# Configuration for intelligent logging
LOG_DIR = "logs/seo_tools"
os.makedirs(LOG_DIR, exist_ok=True)

# Request/Response Models
class BaseResponse(BaseModel):
    """Base response model for all SEO tools"""
    success: bool
    message: str
    timestamp: datetime = Field(default_factory=datetime.utcnow)
    execution_time: Optional[float] = None
    data: Optional[Dict[str, Any]] = None

class ErrorResponse(BaseResponse):
    """Error response model"""
    error_type: str
    error_details: Optional[str] = None
    traceback: Optional[str] = None

class MetaDescriptionRequest(BaseModel):
    """Request model for meta description generation"""
    keywords: List[str] = Field(..., description="Target keywords for meta description")
    tone: str = Field(default="General", description="Desired tone for meta description")
    search_intent: str = Field(default="Informational Intent", description="Search intent type")
    language: str = Field(default="English", description="Preferred language")
    custom_prompt: Optional[str] = Field(None, description="Custom prompt for generation")
    
    @validator('keywords')
    def validate_keywords(cls, v):
        if not v or len(v) == 0:
            raise ValueError("At least one keyword is required")
        return v

class PageSpeedRequest(BaseModel):
    """Request model for PageSpeed Insights analysis"""
    url: HttpUrl = Field(..., description="URL to analyze")
    strategy: str = Field(default="DESKTOP", description="Analysis strategy (DESKTOP/MOBILE)")
    locale: str = Field(default="en", description="Locale for analysis")
    categories: List[str] = Field(default=["performance", "accessibility", "best-practices", "seo"])

class SitemapAnalysisRequest(BaseModel):
    """Request model for sitemap analysis"""
    sitemap_url: HttpUrl = Field(..., description="Sitemap URL to analyze")
    analyze_content_trends: bool = Field(default=True, description="Analyze content trends")
    analyze_publishing_patterns: bool = Field(default=True, description="Analyze publishing patterns")

class ImageAltRequest(BaseModel):
    """Request model for image alt text generation"""
    image_url: Optional[HttpUrl] = Field(None, description="URL of image to analyze")
    context: Optional[str] = Field(None, description="Context about the image")
    keywords: Optional[List[str]] = Field(None, description="Keywords to include in alt text")

class OpenGraphRequest(BaseModel):
    """Request model for OpenGraph tag generation"""
    url: HttpUrl = Field(..., description="URL for OpenGraph tags")
    title_hint: Optional[str] = Field(None, description="Hint for title")
    description_hint: Optional[str] = Field(None, description="Hint for description")
    platform: str = Field(default="General", description="Platform (General/Facebook/Twitter)")

class OnPageSEORequest(BaseModel):
    """Request model for on-page SEO analysis"""
    url: HttpUrl = Field(..., description="URL to analyze")
    target_keywords: Optional[List[str]] = Field(None, description="Target keywords for analysis")
    analyze_images: bool = Field(default=True, description="Include image analysis")
    analyze_content_quality: bool = Field(default=True, description="Analyze content quality")

class TechnicalSEORequest(BaseModel):
    """Request model for technical SEO analysis"""
    url: HttpUrl = Field(..., description="URL to crawl and analyze")
    crawl_depth: int = Field(default=3, description="Crawl depth (1-5)")
    include_external_links: bool = Field(default=True, description="Include external link analysis")
    analyze_performance: bool = Field(default=True, description="Include performance analysis")

class WorkflowRequest(BaseModel):
    """Request model for SEO workflow execution"""
    website_url: HttpUrl = Field(..., description="Primary website URL")
    workflow_type: str = Field(..., description="Type of workflow to execute")
    competitors: Optional[List[HttpUrl]] = Field(None, description="Competitor URLs (max 5)")
    target_keywords: Optional[List[str]] = Field(None, description="Target keywords")
    custom_parameters: Optional[Dict[str, Any]] = Field(None, description="Custom workflow parameters")

# Exception Handler
async def handle_seo_tool_exception(func_name: str, error: Exception, request_data: Dict) -> ErrorResponse:
    """Handle exceptions from SEO tools with intelligent logging"""
    error_id = f"seo_{func_name}_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}"
    error_msg = str(error)
    error_trace = traceback.format_exc()
    
    # Log error with structured data
    error_log = {
        "error_id": error_id,
        "function": func_name,
        "error_type": type(error).__name__,
        "error_message": error_msg,
        "request_data": request_data,
        "traceback": error_trace,
        "timestamp": datetime.utcnow().isoformat()
    }
    
    logger.error(f"SEO Tool Error [{error_id}]: {error_msg}")
    
    # Save error to file
    await save_to_file(f"{LOG_DIR}/errors.jsonl", error_log)
    
    return ErrorResponse(
        success=False,
        message=f"Error in {func_name}: {error_msg}",
        error_type=type(error).__name__,
        error_details=error_msg,
        traceback=error_trace if os.getenv("DEBUG", "false").lower() == "true" else None
    )

# SEO Tool Endpoints

@router.post("/meta-description", response_model=BaseResponse)
@log_api_call
async def generate_meta_description(
    request: MetaDescriptionRequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    Generate AI-powered SEO meta descriptions
    
    Generates compelling, SEO-optimized meta descriptions based on keywords,
    tone, and search intent using advanced AI analysis.
    """
    start_time = datetime.utcnow()
    
    try:
        service = MetaDescriptionService()
        result = await service.generate_meta_description(
            keywords=request.keywords,
            tone=request.tone,
            search_intent=request.search_intent,
            language=request.language,
            custom_prompt=request.custom_prompt
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "meta_description_generation",
            "keywords_count": len(request.keywords),
            "tone": request.tone,
            "language": request.language,
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/operations.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="Meta description generated successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("generate_meta_description", e, request.dict())

@router.post("/pagespeed-analysis", response_model=BaseResponse)
@log_api_call
async def analyze_pagespeed(
    request: PageSpeedRequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    Analyze website performance using Google PageSpeed Insights
    
    Provides comprehensive performance analysis including Core Web Vitals,
    accessibility, SEO, and best practices scores with AI-enhanced insights.
    """
    start_time = datetime.utcnow()
    
    try:
        service = PageSpeedService()
        result = await service.analyze_pagespeed(
            url=str(request.url),
            strategy=request.strategy,
            locale=request.locale,
            categories=request.categories
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "pagespeed_analysis",
            "url": str(request.url),
            "strategy": request.strategy,
            "categories": request.categories,
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/operations.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="PageSpeed analysis completed successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("analyze_pagespeed", e, request.dict())

@router.post("/sitemap-analysis", response_model=BaseResponse)
@log_api_call
async def analyze_sitemap(
    request: SitemapAnalysisRequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    Analyze website sitemap for content structure and trends
    
    Provides insights into content distribution, publishing patterns,
    and SEO opportunities with AI-powered recommendations.
    """
    start_time = datetime.utcnow()
    
    try:
        service = SitemapService()
        result = await service.analyze_sitemap(
            sitemap_url=str(request.sitemap_url),
            analyze_content_trends=request.analyze_content_trends,
            analyze_publishing_patterns=request.analyze_publishing_patterns
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "sitemap_analysis",
            "sitemap_url": str(request.sitemap_url),
            "urls_found": result.get("total_urls", 0),
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/operations.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="Sitemap analysis completed successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("analyze_sitemap", e, request.dict())

@router.post("/image-alt-text", response_model=BaseResponse)
@log_api_call
async def generate_image_alt_text(
    request: ImageAltRequest = None,
    image_file: UploadFile = File(None),
    background_tasks: BackgroundTasks = BackgroundTasks()
) -> Union[BaseResponse, ErrorResponse]:
    """
    Generate AI-powered alt text for images
    
    Creates SEO-optimized alt text for images using advanced AI vision
    models with context-aware keyword integration.
    """
    start_time = datetime.utcnow()
    
    try:
        service = ImageAltService()
        
        if image_file:
            # Handle uploaded file
            with tempfile.NamedTemporaryFile(delete=False, suffix=f".{image_file.filename.split('.')[-1]}") as tmp_file:
                content = await image_file.read()
                tmp_file.write(content)
                tmp_file_path = tmp_file.name
            
            result = await service.generate_alt_text_from_file(
                image_path=tmp_file_path,
                context=request.context if request else None,
                keywords=request.keywords if request else None
            )
            
            # Cleanup
            os.unlink(tmp_file_path)
            
        elif request and request.image_url:
            result = await service.generate_alt_text_from_url(
                image_url=str(request.image_url),
                context=request.context,
                keywords=request.keywords
            )
        else:
            raise ValueError("Either image_file or image_url must be provided")
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "image_alt_text_generation",
            "has_image_file": image_file is not None,
            "has_image_url": request.image_url is not None if request else False,
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/operations.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="Image alt text generated successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("generate_image_alt_text", e, 
                                              request.dict() if request else {})

@router.post("/opengraph-tags", response_model=BaseResponse)
@log_api_call
async def generate_opengraph_tags(
    request: OpenGraphRequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    Generate OpenGraph tags for social media optimization
    
    Creates platform-specific OpenGraph tags optimized for Facebook,
    Twitter, and other social platforms with AI-powered content analysis.
    """
    start_time = datetime.utcnow()
    
    try:
        service = OpenGraphService()
        result = await service.generate_opengraph_tags(
            url=str(request.url),
            title_hint=request.title_hint,
            description_hint=request.description_hint,
            platform=request.platform
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "opengraph_generation",
            "url": str(request.url),
            "platform": request.platform,
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/operations.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="OpenGraph tags generated successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("generate_opengraph_tags", e, request.dict())

@router.post("/on-page-analysis", response_model=BaseResponse)
@log_api_call
async def analyze_on_page_seo(
    request: OnPageSEORequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    Comprehensive on-page SEO analysis
    
    Analyzes meta tags, content quality, keyword optimization, internal linking,
    and provides actionable AI-powered recommendations for improvement.
    """
    start_time = datetime.utcnow()
    
    try:
        service = OnPageSEOService()
        result = await service.analyze_on_page_seo(
            url=str(request.url),
            target_keywords=request.target_keywords,
            analyze_images=request.analyze_images,
            analyze_content_quality=request.analyze_content_quality
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "on_page_seo_analysis",
            "url": str(request.url),
            "target_keywords_count": len(request.target_keywords) if request.target_keywords else 0,
            "seo_score": result.get("overall_score", 0),
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/operations.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="On-page SEO analysis completed successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("analyze_on_page_seo", e, request.dict())

@router.post("/technical-seo", response_model=BaseResponse)
@log_api_call
async def analyze_technical_seo(
    request: TechnicalSEORequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    Technical SEO analysis and crawling
    
    Performs comprehensive technical SEO audit including site structure,
    crawlability, indexability, and performance with AI-enhanced insights.
    """
    start_time = datetime.utcnow()
    
    try:
        service = TechnicalSEOService()
        result = await service.analyze_technical_seo(
            url=str(request.url),
            crawl_depth=request.crawl_depth,
            include_external_links=request.include_external_links,
            analyze_performance=request.analyze_performance
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "technical_seo_analysis",
            "url": str(request.url),
            "crawl_depth": request.crawl_depth,
            "pages_crawled": result.get("pages_crawled", 0),
            "issues_found": len(result.get("issues", [])),
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/operations.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="Technical SEO analysis completed successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("analyze_technical_seo", e, request.dict())

# Workflow Endpoints

@router.post("/workflow/website-audit", response_model=BaseResponse)
@log_api_call
async def execute_website_audit(
    request: WorkflowRequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    Complete website SEO audit workflow
    
    Executes a comprehensive SEO audit combining on-page analysis,
    technical SEO, performance analysis, and competitive intelligence.
    """
    start_time = datetime.utcnow()
    
    try:
        service = EnterpriseSEOService()
        result = await service.execute_complete_audit(
            website_url=str(request.website_url),
            competitors=[str(comp) for comp in request.competitors] if request.competitors else [],
            target_keywords=request.target_keywords or []
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "website_audit_workflow",
            "website_url": str(request.website_url),
            "competitors_count": len(request.competitors) if request.competitors else 0,
            "overall_score": result.get("overall_score", 0),
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/workflows.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="Website audit completed successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("execute_website_audit", e, request.dict())

@router.post("/workflow/content-analysis", response_model=BaseResponse)
@log_api_call
async def execute_content_analysis(
    request: WorkflowRequest,
    background_tasks: BackgroundTasks
) -> Union[BaseResponse, ErrorResponse]:
    """
    AI-powered content analysis workflow
    
    Analyzes content gaps, opportunities, and competitive positioning
    with AI-generated strategic recommendations for content creators.
    """
    start_time = datetime.utcnow()
    
    try:
        service = ContentStrategyService()
        result = await service.analyze_content_strategy(
            website_url=str(request.website_url),
            competitors=[str(comp) for comp in request.competitors] if request.competitors else [],
            target_keywords=request.target_keywords or [],
            custom_parameters=request.custom_parameters or {}
        )
        
        execution_time = (datetime.utcnow() - start_time).total_seconds()
        
        # Log successful operation
        log_data = {
            "operation": "content_analysis_workflow",
            "website_url": str(request.website_url),
            "content_gaps_found": len(result.get("content_gaps", [])),
            "opportunities_identified": len(result.get("opportunities", [])),
            "execution_time": execution_time,
            "success": True
        }
        background_tasks.add_task(save_to_file, f"{LOG_DIR}/workflows.jsonl", log_data)
        
        return BaseResponse(
            success=True,
            message="Content analysis completed successfully",
            execution_time=execution_time,
            data=result
        )
        
    except Exception as e:
        return await handle_seo_tool_exception("execute_content_analysis", e, request.dict())

# Health and Status Endpoints

@router.get("/health", response_model=BaseResponse)
async def health_check() -> BaseResponse:
    """Health check endpoint for SEO tools"""
    return BaseResponse(
        success=True,
        message="AI SEO Tools API is healthy",
        data={
            "status": "operational",
            "available_tools": [
                "meta_description",
                "pagespeed_analysis", 
                "sitemap_analysis",
                "image_alt_text",
                "opengraph_tags",
                "on_page_analysis",
                "technical_seo",
                "website_audit",
                "content_analysis"
            ],
            "version": "1.0.0"
        }
    )

@router.get("/tools/status", response_model=BaseResponse)
async def get_tools_status() -> BaseResponse:
    """Get status of all SEO tools and their dependencies"""
    
    tools_status = {}
    overall_healthy = True
    
    # Check each service
    services = [
        ("meta_description", MetaDescriptionService),
        ("pagespeed", PageSpeedService),
        ("sitemap", SitemapService),
        ("image_alt", ImageAltService),
        ("opengraph", OpenGraphService),
        ("on_page_seo", OnPageSEOService),
        ("technical_seo", TechnicalSEOService),
        ("enterprise_seo", EnterpriseSEOService),
        ("content_strategy", ContentStrategyService)
    ]
    
    for service_name, service_class in services:
        try:
            service = service_class()
            status = await service.health_check() if hasattr(service, 'health_check') else {"status": "unknown"}
            tools_status[service_name] = {
                "healthy": status.get("status") == "operational",
                "details": status
            }
            if not tools_status[service_name]["healthy"]:
                overall_healthy = False
        except Exception as e:
            tools_status[service_name] = {
                "healthy": False,
                "error": str(e)
            }
            overall_healthy = False
    
    return BaseResponse(
        success=overall_healthy,
        message="Tools status check completed",
        data={
            "overall_healthy": overall_healthy,
            "tools": tools_status,
            "timestamp": datetime.utcnow().isoformat()
        }
    )