"""
客户管理 Service 层
REST API 路由 和 MCP 工具 共用此层函数
"""

from __future__ import annotations

import uuid
from datetime import datetime

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

from app.core.exceptions import BizException, ForbiddenException, NotFoundException
from app.models.crm import CrmCustomer
from app.schemas.auth import CurrentUserPayload
from app.schemas.crm import (
    CustomerCreate,
    CustomerListResponse,
    CustomerResponse,
    CustomerUpdate,
)


# ── ORM → Response ───────────────────────────────────────
def _to_response(c: CrmCustomer) -> CustomerResponse:
    return CustomerResponse(
        id=c.id,
        name=c.name,
        level=c.level,
        industry=c.industry,
        contact=c.contact,
        phone=c.phone,
        email=c.email,
        address=c.address,
        ai_score=float(c.ai_score or 0),
        ai_persona=c.ai_persona,
        owner_id=c.owner_id,
        owner_name=c.owner.real_name if c.owner else None,
        status=c.status,
        is_deleted=c.is_deleted,
        created_at=c.created_at,
        updated_at=c.updated_at,
    )


# ── 权限校验 ─────────────────────────────────────────────
def _check_access(customer: CrmCustomer, user: CurrentUserPayload) -> None:
    if user.data_scope == "all":
        return
    if user.data_scope == "dept_and_sub":
        return  # 简化版：放通本部门
    # data_scope == 'self'
    if customer.owner_id != user.user_id:
        raise ForbiddenException("无权访问该客户（数据权限：仅本人）")


# ── Service Functions ────────────────────────────────────

async def create_customer(
    db: AsyncSession,
    user: CurrentUserPayload,
    body: CustomerCreate,
) -> CustomerResponse:
    customer = CrmCustomer(
        name=body.name,
        level=body.level,
        industry=body.industry,
        contact=body.contact,
        phone=body.phone,
        email=body.email,
        address=body.address,
        status=body.status,
        owner_id=user.user_id,
    )
    db.add(customer)
    await db.commit()
    await db.refresh(customer)
    return _to_response(customer)


async def list_customers(
    db: AsyncSession,
    user: CurrentUserPayload,
    page: int = 1,
    size: int = 20,
    keyword: str | None = None,
    level: str | None = None,
    include_archived: bool = False,
) -> CustomerListResponse:
    if include_archived:
        base_where = []  # 不过滤 is_deleted
    else:
        base_where = [CrmCustomer.is_deleted.is_(False)]

    # ── 数据域隔离 ──
    if user.data_scope == "self":
        base_where.append(CrmCustomer.owner_id == user.user_id)
    elif user.data_scope == "dept_and_sub":
        if user.dept_id is not None:
            from app.models.sys import SysUser
            sub = select(SysUser.id).where(
                SysUser.dept_id == user.dept_id,
                SysUser.is_deleted.is_(False),
            )
            base_where.append(CrmCustomer.owner_id.in_(sub))

    if keyword:
        base_where.append(CrmCustomer.name.ilike(f"%{keyword}%"))
    if level:
        base_where.append(CrmCustomer.level == level)

    total = (
        await db.execute(select(func.count()).select_from(CrmCustomer).where(*base_where))
    ).scalar() or 0

    stmt = (
        select(CrmCustomer)
        .where(*base_where)
        .order_by(CrmCustomer.created_at.desc())
        .offset((page - 1) * size)
        .limit(size)
    )
    customers = (await db.execute(stmt)).scalars().all()

    return CustomerListResponse(
        total=total,
        items=[_to_response(c) for c in customers],
        page=page,
        size=size,
    )


async def get_customer(
    db: AsyncSession,
    user: CurrentUserPayload,
    customer_id: uuid.UUID,
) -> CustomerResponse:
    stmt = select(CrmCustomer).where(
        CrmCustomer.id == customer_id,
        CrmCustomer.is_deleted.is_(False),
    )
    customer = (await db.execute(stmt)).scalar_one_or_none()
    if customer is None:
        raise NotFoundException("客户不存在或已被删除")

    _check_access(customer, user)
    return _to_response(customer)


async def update_customer(
    db: AsyncSession,
    user: CurrentUserPayload,
    customer_id: uuid.UUID,
    body: CustomerUpdate,
) -> CustomerResponse:
    stmt = select(CrmCustomer).where(
        CrmCustomer.id == customer_id,
        CrmCustomer.is_deleted.is_(False),
    )
    customer = (await db.execute(stmt)).scalar_one_or_none()
    if customer is None:
        raise NotFoundException("客户不存在或已被删除")

    _check_access(customer, user)

    update_data = body.model_dump(exclude_unset=True)
    if not update_data:
        raise BizException(message="未提供任何需要更新的字段")

    update_data["updated_at"] = datetime.utcnow()
    await db.execute(
        update(CrmCustomer).where(CrmCustomer.id == customer_id).values(**update_data)
    )
    await db.commit()

    updated = (
        await db.execute(select(CrmCustomer).where(CrmCustomer.id == customer_id))
    ).scalar_one()
    return _to_response(updated)


async def delete_customer(
    db: AsyncSession,
    user: CurrentUserPayload,
    customer_id: uuid.UUID,
) -> None:
    stmt = select(CrmCustomer).where(
        CrmCustomer.id == customer_id,
        CrmCustomer.is_deleted.is_(False),
    )
    customer = (await db.execute(stmt)).scalar_one_or_none()
    if customer is None:
        raise NotFoundException("客户不存在或已被删除")

    _check_access(customer, user)

    await db.execute(
        update(CrmCustomer)
        .where(CrmCustomer.id == customer_id)
        .values(is_deleted=True, updated_at=datetime.utcnow())
    )
    await db.commit()


async def restore_customer(
    db: AsyncSession,
    user: CurrentUserPayload,
    customer_id: uuid.UUID,
) -> None:
    stmt = select(CrmCustomer).where(
        CrmCustomer.id == customer_id,
        CrmCustomer.is_deleted.is_(True),
    )
    customer = (await db.execute(stmt)).scalar_one_or_none()
    if customer is None:
        raise NotFoundException("客户不存在或未被归档")

    _check_access(customer, user)

    await db.execute(
        update(CrmCustomer)
        .where(CrmCustomer.id == customer_id)
        .values(is_deleted=False, updated_at=datetime.utcnow())
    )
    await db.commit()


async def get_customer_products(
    db: AsyncSession,
    user: CurrentUserPayload,
    customer_id: uuid.UUID,
) -> list[dict]:
    """通过订单反查客户关联的产品 SKU（去重聚合）"""
    from app.models.order import ErpOrder, ErpOrderItem
    from app.models.erp import ProductSku
    from sqlalchemy import desc as sa_desc

    # 确认客户存在
    stmt = select(CrmCustomer).where(CrmCustomer.id == customer_id)
    customer = (await db.execute(stmt)).scalar_one_or_none()
    if customer is None:
        raise NotFoundException("客户不存在")
    _check_access(customer, user)

    # 聚合: 该客户所有订单中的 SKU，含总数量、最近下单时间
    agg_stmt = (
        select(
            ErpOrderItem.sku_id,
            ProductSku.sku_code,
            ProductSku.name.label("sku_name"),
            ProductSku.spec,
            func.sum(ErpOrderItem.qty).label("total_qty"),
            func.max(ErpOrder.order_date).label("last_order_date"),
            func.count(func.distinct(ErpOrder.id)).label("order_count"),
        )
        .join(ErpOrder, ErpOrderItem.order_id == ErpOrder.id)
        .join(ProductSku, ErpOrderItem.sku_id == ProductSku.id)
        .where(
            ErpOrder.customer_id == customer_id,
            ErpOrder.is_deleted.is_(False),
            ErpOrderItem.is_deleted.is_(False),
        )
        .group_by(
            ErpOrderItem.sku_id,
            ProductSku.sku_code,
            ProductSku.name,
            ProductSku.spec,
        )
        .order_by(sa_desc("last_order_date"))
    )
    rows = (await db.execute(agg_stmt)).all()

    return [
        {
            "sku_id": str(r.sku_id),
            "sku_code": r.sku_code,
            "sku_name": r.sku_name,
            "spec": r.spec,
            "total_qty": float(r.total_qty),
            "order_count": r.order_count,
            "last_order_date": r.last_order_date.isoformat() if r.last_order_date else None,
        }
        for r in rows
    ]


async def search_customers(
    db: AsyncSession,
    user: CurrentUserPayload,
    q: str,
    limit: int = 20,
) -> list[dict]:
    """模糊搜索客户，返回精简列表（供远程选择器用）"""
    base_where = [CrmCustomer.is_deleted.is_(False)]

    # 数据域隔离
    if user.data_scope == "self":
        base_where.append(CrmCustomer.owner_id == user.user_id)
    elif user.data_scope == "dept_and_sub":
        if user.dept_id is not None:
            from app.models.sys import SysUser
            sub = select(SysUser.id).where(
                SysUser.dept_id == user.dept_id,
                SysUser.is_deleted.is_(False),
            )
            base_where.append(CrmCustomer.owner_id.in_(sub))

    # 模糊搜索（名称 / 联系人 / 电话）
    from sqlalchemy import or_
    base_where.append(
        or_(
            CrmCustomer.name.ilike(f"%{q}%"),
            CrmCustomer.contact.ilike(f"%{q}%"),
            CrmCustomer.phone.ilike(f"%{q}%"),
        )
    )

    stmt = (
        select(CrmCustomer)
        .where(*base_where)
        .order_by(CrmCustomer.name)
        .limit(limit)
    )
    customers = (await db.execute(stmt)).scalars().all()

    return [
        {
            "id": str(c.id),
            "name": c.name,
            "level": c.level,
            "contact": c.contact,
            "phone": c.phone,
        }
        for c in customers
    ]
