from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
from sqlalchemy.orm import Session
from app.database import get_db
from app.models import ScrapeLog, EmailLog, MealPlan, Recipe
from app.security import require_admin
from app.services.scraper_service import ScraperService, enqueue_scrape
from app.services.feedback_analyzer import FeedbackAnalyzer
from app.services.recipe_discovery import RecipeDiscoveryService
from app.services.recipe_ingestion import RecipeIngestionService
from typing import List, Optional
from datetime import datetime, timedelta
from uuid import UUID
import logging

logger = logging.getLogger(__name__)

router = APIRouter(dependencies=[Depends(require_admin)])


@router.post("/scrape", status_code=202)
def trigger_scrape(
    background_tasks: BackgroundTasks,
    source: str = "lucky_california",
    scrape_type: str = "weekly_ad",
    db: Session = Depends(get_db),
):
    log = enqueue_scrape(
        db,
        source=source,
        scrape_type=scrape_type,
        background_tasks=background_tasks,
    )
    return {"status": "queued", "scrape_log_id": str(log.id)}


@router.get("/logs")
def get_logs(
    limit: int = 50,
    source: Optional[str] = None,
    db: Session = Depends(get_db)
):
    query = db.query(ScrapeLog).order_by(ScrapeLog.started_at.desc())

    if source:
        query = query.filter(ScrapeLog.source == source)

    logs = query.limit(limit).all()
    return {
        "logs": [
            {
                "id": str(log.id),
                "source": log.source,
                "scrape_type": log.scrape_type,
                "status": log.status.value,
                "items_scraped": log.items_scraped,
                "error_message": log.error_message,
                "started_at": log.started_at.isoformat() if log.started_at else None,
                "completed_at": log.completed_at.isoformat() if log.completed_at else None,
                "duration_seconds": log.duration_seconds
            }
            for log in logs
        ]
    }


@router.get("/logs/{log_id}")
def get_log(log_id: str, db: Session = Depends(get_db)):
    log = db.query(ScrapeLog).filter(ScrapeLog.id == log_id).first()
    if not log:
        raise HTTPException(status_code=404, detail="Log not found")
    return {
        "id": str(log.id),
        "source": log.source,
        "scrape_type": log.scrape_type,
        "status": log.status.value,
        "items_scraped": log.items_scraped,
        "error_message": log.error_message,
        "started_at": log.started_at.isoformat() if log.started_at else None,
        "completed_at": log.completed_at.isoformat() if log.completed_at else None,
        "duration_seconds": log.duration_seconds
    }


@router.get("/email-logs")
def get_email_logs(
    limit: int = 50,
    status: Optional[str] = None,
    db: Session = Depends(get_db)
):
    query = db.query(EmailLog).order_by(EmailLog.created_at.desc())

    if status:
        query = query.filter(EmailLog.status == status)

    logs = query.limit(limit).all()
    return {
        "logs": [
            {
                "id": str(log.id),
                "recipient_email": log.recipient_email,
                "recipient_name": log.recipient_name,
                "template": log.template,
                "status": log.status.value,
                "error_message": log.error_message,
                "created_at": log.created_at.isoformat() if log.created_at else None,
                "delivered_at": log.delivered_at.isoformat() if log.delivered_at else None
            }
            for log in logs
        ]
    }


@router.get("/meal-plans")
def get_all_meal_plans(
    limit: int = 10,
    status: Optional[str] = None,
    db: Session = Depends(get_db)
):
    query = db.query(MealPlan).order_by(MealPlan.week_start_date.desc())

    if status:
        query = query.filter(MealPlan.status == status)

    plans = query.limit(limit).all()
    return {
        "meal_plans": [
            {
                "id": str(plan.id),
                "week_start_date": plan.week_start_date.isoformat() if plan.week_start_date else None,
                "status": plan.status.value,
                "total_estimated_cost": float(plan.total_estimated_cost) if plan.total_estimated_cost else None,
                "item_count": len(plan.items) if plan.items else 0,
                "created_at": plan.created_at.isoformat() if plan.created_at else None
            }
            for plan in plans
        ]
    }


@router.post("/test-email")
def test_email(email: str, db: Session = Depends(get_db)):
    from app.services.email import get_email_backend

    html = "<html><body><h1>MealPlanner Test Email</h1><p>This is a test email from MealPlanner.</p></body></html>"
    text = "MealPlanner Test Email\n\nThis is a test email from MealPlanner."

    try:
        backend = get_email_backend()
        backend.send(
            to=email,
            subject="MealPlanner Test Email",
            html=html,
            text=text,
        )
        status = "sent"
    except Exception as e:
        status = f"failed: {e}"

    email_log = EmailLog(
        recipient_email=email,
        template="test",
        status=status,
        created_at=datetime.now()
    )
    db.add(email_log)
    db.commit()
    db.refresh(email_log)

    return {
        "message": f"Test email {status}",
        "email_log_id": str(email_log.id),
        "recipient": email,
        "status": status,
    }


@router.get("/stats")
def get_stats(db: Session = Depends(get_db)):
    from app.models import Recipe, FamilyProfile, Ingredient

    recipe_count = db.query(Recipe).count()
    ingredient_count = db.query(Ingredient).count()
    plan_count = db.query(MealPlan).count()

    return {
        "recipes": recipe_count,
        "ingredients": ingredient_count,
        "meal_plans": plan_count
    }


@router.post("/trigger-images", status_code=200)
def trigger_images(
    limit: int = 10,
    missing_only: bool = True,
    force: bool = False,
    recipe_id: Optional[UUID] = None,
    db: Session = Depends(get_db),
):
    from app.services.image_generation import generate_images_batch

    recipe_ids = [str(recipe_id)] if recipe_id else None
    result = generate_images_batch(
        db,
        recipe_ids=recipe_ids,
        missing_only=missing_only,
        force=force,
        limit=limit,
    )
    return result


@router.post("/trigger-discovery", status_code=200)
def trigger_discovery(
    family_profile_id: UUID,
    force: bool = False,
    db: Session = Depends(get_db),
):
    from uuid import UUID as UUIDType
    
    profile = (
        db.query(FamilyProfile)
        .filter(FamilyProfile.id == family_profile_id)
        .first()
    )
    if not profile:
        raise HTTPException(status_code=404, detail="Family profile not found")

    analyzer = FeedbackAnalyzer(lookback_weeks=4)
    analysis = analyzer.analyze(db, profile.id)

    if not analysis.discovery_queries and not force:
        return {"status": "skipped", "reason": "No discovery queries and force=false"}

    discovery = RecipeDiscoveryService()
    if not analysis.discovery_queries and force:
        queries = ["popular recipes"]
    else:
        queries = analysis.discovery_queries
    
    candidates = discovery.discover(queries)
    if not candidates:
        return {"status": "no_candidates"}

    ingestion = RecipeIngestionService()
    added = ingestion.ingest(
        db, profile.id, candidates, analysis.to_dict()
    )
    logger.info("Manual discovery: added %d recipes for family %s", added, profile.id)
    return {
        "status": "success",
        "candidates_found": len(candidates),
        "recipes_added": added,
        "discovery_queries": queries,
        "confidence": analysis.confidence,
    }