"""Application settings (admin): random amount/shipping ranges, invoice number format,
default per-account limits, send pacing, attachment filename prefixes, compliance toggles."""
from typing import Optional

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

from app.api.deps import get_current_user, get_db, require_csrf
from app.core.config import settings as cfg
from app.core.security import log_audit
from app.models import ApplicationSettings, User
from app.services.campaign_engine import get_setting

router = APIRouter(prefix="/settings", tags=["settings"])


class SettingIn(BaseModel):
    key: str = Field(min_length=1, max_length=150)
    value: object = None
    category: str = "general"
    description: str = ""


class BatchSettingsIn(BaseModel):
    values: dict


# Known settings keys with validation constraints
SETTING_DEFS = {
    "amount_min": {"type": "float", "min": 0, "max": 100000, "default": cfg.AMOUNT_MIN,
                   "label": "Random amount minimum ($)", "category": "financial"},
    "amount_max": {"type": "float", "min": 0, "max": 100000, "default": cfg.AMOUNT_MAX,
                   "label": "Random amount maximum ($)", "category": "financial"},
    "shipping_min": {"type": "float", "min": 0, "max": 10000, "default": cfg.SHIPPING_MIN,
                     "label": "Random shipping minimum ($)", "category": "financial"},
    "shipping_max": {"type": "float", "min": 0, "max": 10000, "default": cfg.SHIPPING_MAX,
                     "label": "Random shipping maximum ($)", "category": "financial"},
    "invoice_format": {"type": "str", "max_len": 80, "default": cfg.INVOICE_NUMBER_FORMAT,
                       "label": "Invoice number format (tokens: {prefix},{R#},{r#},{d#},{seq4},{date},{hash})",
                       "category": "financial"},
    "invoice_prefix": {"type": "str", "max_len": 12, "default": "INV",
                       "label": "Invoice prefix", "category": "financial"},
    "default_daily_limit": {"type": "int", "min": 1, "max": 2000, "default": 500,
                            "label": "Default per-account daily send limit", "category": "limits"},
    "default_campaign_limit": {"type": "int", "min": 1, "max": 2000, "default": 200,
                               "label": "Default per-account per-campaign limit", "category": "limits"},
    "default_max_per_account": {"type": "int", "min": 1, "max": 2000, "default": 200,
                                "label": "Default max sends per account per campaign", "category": "limits"},
    "default_send_interval": {"type": "float", "min": 0.5, "max": 3600, "default": 1.0,
                              "label": "Default seconds between sends per account", "category": "limits"},
    "default_rate_per_minute": {"type": "int", "min": 1, "max": 600, "default": 60,
                                "label": "Default max sends per minute (per account)", "category": "limits"},
    "attachment_kind": {"type": "str", "max_len": 20, "default": "invoice",
                        "label": "Attachment filename prefix (invoice|order|receipt)",
                        "category": "attachments"},
    "unsubscribe_enabled": {"type": "bool", "default": True,
                            "label": "Enable unsubscribe links globally", "category": "compliance"},
    "unsubscribe_base_url": {"type": "str", "max_len": 300, "default": "",
======
    if applied:
        await log_audit(db, user.id, "settings.save_batch", "application_setting", None,
                        {"keys": list(applied.keys())})
    return {"applied": applied, "errors": errors}


@router.post("/reset")
async def reset_setting(payload: SettingIn, db: AsyncSession = Depends(get_db),
                        user: User = Depends(get_current_user),
                        _: None = Depends(require_csrf)):
    """Reset one setting to its default value (deletes the DB row)."""
    if payload.key not in SETTING_DEFS:
        raise HTTPException(status_code=400, detail="Unknown setting key")
    row = await db.execute(
        select(ApplicationSettings).where(ApplicationSettings.key == payload.key))
    row = row.scalar()
    if row:
        await db.delete(row)
        await db.commit()
    await log_audit(db, user.id, "settings.reset", "application_setting", None,
                    {"key": payload.key})
    return {"key": payload.key, "value": SETTING_DEFS[payload.key]["default"]}


@router.post("/reset-all")
async def reset_all_settings(db: AsyncSession = Depends(get_db),
                             user: User = Depends(get_current_user),
                             _: None = Depends(require_csrf)):
    rows = (await db.execute(
        select(ApplicationSettings).where(ApplicationSettings.key.in_(SETTING_DEFS.keys()))
    )).scalars().all()
    for r in rows:
        await db.delete(r)
    await db.commit()
    await log_audit(db, user.id, "settings.reset_all", "application_setting", None,
                    {"reset": len(rows)})
    return {"reset": len(rows)}
