"""OEM 桌面配置 CRUD（按当前 OEM 用户的 oem 记录隔离）。"""

from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.oem_resolve import resolve_oem_id
from app.models.desktopConfig import DesktopConfig
from app.models.user import User
from app.schemas.admin_desktop_config import DesktopConfigCreate, DesktopConfigUpdate

DEFAULT_PAGE_SIZE = 20
MAX_PAGE_SIZE = 200

# 新 OEM 首次访问时写入的默认桌面配置（oem_id 由 resolve_oem_id 动态填入）
DEFAULT_DESKTOP_CONFIG_SEED: tuple[tuple[str, str], ...] = (
    ("BAILIAN_API_KEY", "sk-fc1ae323e01947dc9e054aad121796aa"),
    ("BAILIAN_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1"),
    ("ASR_MODE", "online"),
    ("OSS_ACCESS_KEY_ID", "LTAI5tSUJiy9NTBdX5sQeC9f"),
    ("OSS_ACCESS_KEY_SECRET", "H7D1SjRYy94vCXC7nxIAuZQvaNjBx3"),
    ("OSS_BUCKET", "jianhualinshi"),
    ("OSS_REGION", "oss-cn-beijing"),
    ("LLM_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3/chat/completions"),
    ("LLM_MODE_ID", "doubao-seed-2-0-mini-260215"),
    ("LLM_API_KEY", "ebff7c25-d00f-483d-94bb-8d1c18b51ddd"),
    ("VIDEO_GEN_MODE", "online"),
    ("INFINITETALK_API_URL", "http://www.baidu.com"),
    ("RUNNINGHUB_WORKFLOW_ID", "2013514129943826433"),
    ("RUNNINGHUB_API_KEY", "389cc5f561d742fb9a9cf26f37dda0d3"),
)


class OemDesktopConfigError(Exception):
    def __init__(self, message: str) -> None:
        self.message = message
        super().__init__(message)


# 路由层沿用 AdminDesktopConfigError 名称
AdminDesktopConfigError = OemDesktopConfigError

async def _count_by_oem(db: AsyncSession, oem_id: int) -> int:
    stmt = select(func.count()).select_from(DesktopConfig).where(DesktopConfig.oem_id == oem_id)
    return await db.scalar(stmt) or 0


async def ensure_default_desktop_configs(db: AsyncSession, oem_id: int) -> None:
    """当前 OEM 无任何配置时写入默认键值。"""
    if await _count_by_oem(db, oem_id) > 0:
        return
    for name, value in DEFAULT_DESKTOP_CONFIG_SEED:
        db.add(DesktopConfig(name=name, value=value, oem_id=oem_id))
    await db.flush()


async def list_all_as_map(db: AsyncSession, oem_id: int) -> dict[str, str]:
    await ensure_default_desktop_configs(db, oem_id)
    result = await db.execute(select(DesktopConfig).where(DesktopConfig.oem_id == oem_id))
    rows = result.scalars().all()
    return {row.name: row.value for row in rows}


async def list_configs(
    db: AsyncSession,
    *,
    oem_user: User,
    page: int = 1,
    page_size: int = DEFAULT_PAGE_SIZE,
    keyword: str | None = None,
) -> tuple[list[DesktopConfig], int]:
    oem_id = await resolve_oem_id(db, oem_user)
    await ensure_default_desktop_configs(db, oem_id)
    page_size = min(max(page_size, 1), MAX_PAGE_SIZE)
    page = max(page, 1)
    offset = (page - 1) * page_size

    filters = [DesktopConfig.oem_id == oem_id]
    if keyword:
        like = f"%{keyword.strip()}%"
        filters.append(DesktopConfig.name.ilike(like))

    count_stmt = select(func.count()).select_from(DesktopConfig).where(*filters)
    list_stmt = (
        select(DesktopConfig)
        .where(*filters)
        .order_by(DesktopConfig.name.asc())
        .offset(offset)
        .limit(page_size)
    )

    total = await db.scalar(count_stmt) or 0
    result = await db.scalars(list_stmt)
    return list(result.all()), total


async def create_config(
    db: AsyncSession,
    body: DesktopConfigCreate,
    *,
    oem_user: User,
) -> DesktopConfig:
    oem_id = await resolve_oem_id(db, oem_user)
    existing = await db.scalar(
        select(DesktopConfig).where(
            DesktopConfig.name == body.name,
            DesktopConfig.oem_id == oem_id,
        )
    )
    if existing is not None:
        raise OemDesktopConfigError("配置键名已存在")

    row = DesktopConfig(
        name=body.name,
        value=body.value,
        mark=body.mark,
        oem_id=oem_id,
    )
    db.add(row)
    await db.flush()
    await db.refresh(row)
    return row


async def _get_owned_config(
    db: AsyncSession,
    config_id: int,
    *,
    oem_user: User,
) -> DesktopConfig:
    oem_id = await resolve_oem_id(db, oem_user)
    row = await db.get(DesktopConfig, config_id)
    if row is None or row.oem_id != oem_id:
        raise OemDesktopConfigError("配置不存在")
    return row


async def update_config(
    db: AsyncSession,
    config_id: int,
    body: DesktopConfigUpdate,
    *,
    oem_user: User,
) -> DesktopConfig:
    row = await _get_owned_config(db, config_id, oem_user=oem_user)

    if body.name is not None and body.name != row.name:
        taken = await db.scalar(
            select(DesktopConfig).where(
                DesktopConfig.name == body.name,
                DesktopConfig.oem_id == row.oem_id,
                DesktopConfig.id != config_id,
            )
        )
        if taken is not None:
            raise OemDesktopConfigError("配置键名已存在")
        row.name = body.name

    if body.value is not None:
        row.value = body.value

    if body.mark is not None:
        row.mark = body.mark

    await db.flush()
    await db.refresh(row)
    return row


async def delete_config(
    db: AsyncSession,
    config_id: int,
    *,
    oem_user: User,
) -> None:
    row = await _get_owned_config(db, config_id, oem_user=oem_user)
    await db.delete(row)
