"""Settings, health and local data management.

LeadPilot stores everything in a local SQLite file. Nothing is sent anywhere, and
this router is where the user can inspect or erase that local data.
"""

from __future__ import annotations

from typing import Any

from fastapi import APIRouter, Depends, Query
from sqlalchemy import delete, func, select, update
from sqlalchemy.orm import Session

from app import __version__
from app.config import settings
from app.database import get_db
from app.models import (
    AnalyticsEvent,
    Campaign,
    ImportHistory,
    Lead,
    LeadScore,
    MessageTemplate,
    OutreachActivity,
    OutreachTask,
    Reply,
    Rule,
    RuleGroup,
    User,
)
from app.schemas.base import Message
from app.schemas.outreach import AppSettings, UserSettings, UserSettingsRead

router = APIRouter(tags=["system"])


@router.get("/health")
def health() -> dict[str, Any]:
    return {
        "status": "ok",
        "app": settings.app_name,
        "version": __version__,
        "usesAi": False,
        "database": settings.database_url.split("///")[-1],
    }


@router.get("/settings/user", response_model=UserSettingsRead)
def get_user_settings(db: Session = Depends(get_db)) -> UserSettingsRead:
    user = db.scalars(select(User).order_by(User.id)).first()
    if user is None:
        user = User(name="LeadPilot User")
        db.add(user)
        db.commit()
        db.refresh(user)
    return UserSettingsRead.model_validate(user)


@router.put("/settings/user", response_model=UserSettingsRead)
def update_user_settings(payload: UserSettings, db: Session = Depends(get_db)) -> UserSettingsRead:
    user = db.scalars(select(User).order_by(User.id)).first()
    if user is None:
        user = User()
        db.add(user)
    for key, value in payload.model_dump(exclude_unset=True).items():
        setattr(user, key, value)
    db.commit()
    db.refresh(user)
    return UserSettingsRead.model_validate(user)


@router.get("/settings/app", response_model=AppSettings)
def get_app_settings(db: Session = Depends(get_db)) -> AppSettings:
    first_active = db.scalars(
        select(Campaign).where(Campaign.status == "active").order_by(Campaign.id)
    ).first()
    return AppSettings(
        default_campaign_id=first_active.id if first_active else None,
        followup_days=settings.followup_days,
        app_name=settings.app_name,
        version=__version__,
    )


@router.get("/settings/storage")
def storage_stats(db: Session = Depends(get_db)) -> dict[str, int]:
    """Row counts per table, shown on the Settings > Data storage panel."""
    models = {
        "campaigns": Campaign,
        "leads": Lead,
        "leadScores": LeadScore,
        "rules": Rule,
        "ruleGroups": RuleGroup,
        "templates": MessageTemplate,
        "tasks": OutreachTask,
        "activities": OutreachActivity,
        "replies": Reply,
        "imports": ImportHistory,
        "analyticsEvents": AnalyticsEvent,
    }
    return {
        key: int(db.scalar(select(func.count()).select_from(model)) or 0)
        for key, model in models.items()
    }


@router.delete("/settings/data", response_model=Message)
def clear_all_data(
    db: Session = Depends(get_db),
    keep_rules: bool = Query(default=False, alias="keepRules"),
    keep_templates: bool = Query(default=False, alias="keepTemplates"),
) -> Message:
    """Clear all local data. This is irreversible and never touches LinkedIn."""
    ordered = [
        AnalyticsEvent,
        OutreachActivity,
        Reply,
        OutreachTask,
        LeadScore,
        Lead,
        ImportHistory,
    ]
    if not keep_rules:
        ordered.extend([Rule, RuleGroup])
    if not keep_templates:
        ordered.append(MessageTemplate)

    for model in ordered:
        db.execute(delete(model))

    # Campaign-scoped rules and templates cascade away with their campaign, so
    # anything the user asked to keep has to be detached into the global scope
    # first - otherwise "keep my rules" silently loses every campaign rule.
    if keep_rules:
        db.execute(update(Rule).values(campaign_id=None, group_id=None))
        db.execute(update(RuleGroup).values(campaign_id=None))
    if keep_templates:
        db.execute(update(MessageTemplate).values(campaign_id=None))
    db.flush()

    db.execute(update(Campaign).values(default_template_id=None))
    db.execute(delete(Campaign))
    db.commit()
    return Message(detail="All local LeadPilot data has been deleted from this machine")


@router.post("/settings/seed", response_model=Message)
def seed_demo(db: Session = Depends(get_db), reset: bool = False) -> Message:
    """(Re)create the demo campaign, rules, templates and prospects."""
    from app.services.seed_service import seed_all

    summary = seed_all(db, reset=reset)
    return Message(detail=f"Seeded {summary['leads']} prospects into '{summary['campaign']}'")
