import re
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload

from app.api.deps import get_db, get_admin_user
from app.core.models.user import User
from app.core.models.product import Product, ProductImage, ProductVariant
from app.core.models.product_template import (
    ProductTemplate, TemplateImage, TemplateVariant,
    TemplateCollection, template_collection_items, tenant_visible_collections,
)
from app.schemas.product_template import (
    TemplateListOut, TemplateDetailOut, CollectionBrief,
    TemplateImportRequest, TemplateImportResult, TemplateSourceOut,
)

router = APIRouter(
    prefix="/admin/templates",
    tags=["租户-商品模板"],
)


def _slugify(name: str) -> str:
    s = re.sub(r"[^\w\s-]", "", name.lower())
    return re.sub(r"[-\s]+", "-", s).strip("-")


@router.get("/collections", response_model=list[CollectionBrief])
async def my_collections(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(TemplateCollection)
        .join(tenant_visible_collections)
        .where(tenant_visible_collections.c.tenant_id == current_user.tenant_id)
        .order_by(TemplateCollection.sort_order)
    )
    return [CollectionBrief.model_validate(c) for c in result.scalars().all()]


@router.get("/", response_model=list[TemplateListOut])
async def browse_templates(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
    collection_id: int | None = None,
    keyword: str | None = None,
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
):
    visible_cids = (
        select(tenant_visible_collections.c.collection_id)
        .where(tenant_visible_collections.c.tenant_id == current_user.tenant_id)
    )
    q = (
        select(ProductTemplate)
        .join(template_collection_items)
        .where(
            template_collection_items.c.collection_id.in_(visible_cids),
            ProductTemplate.status == "approved",
        )
        .options(
            selectinload(ProductTemplate.images),
            selectinload(ProductTemplate.collections),
        )
    )
    if collection_id:
        q = q.where(template_collection_items.c.collection_id == collection_id)
    if keyword:
        like = f"%{keyword}%"
        q = q.where(ProductTemplate.name.ilike(like) | ProductTemplate.sku.ilike(like))
    q = q.order_by(ProductTemplate.created_at.desc())
    q = q.offset((page - 1) * page_size).limit(page_size)

    result = await db.execute(q)
    templates = result.scalars().unique().all()

    out = []
    for t in templates:
        primary = next((img for img in t.images if img.is_primary), None)
        cover = primary.url if primary else (t.images[0].url if t.images else None)
        out.append(TemplateListOut(
            id=t.id, sku=t.sku, name=t.name, name_en=t.name_en,
            base_price=float(t.base_price) if t.base_price else None,
            status=t.status, cover_url=cover,
            source_count=0, import_count=0,
            collections=[CollectionBrief.model_validate(c) for c in t.collections],
            created_at=t.created_at,
        ))
    return out


@router.get("/{template_id}", response_model=TemplateDetailOut)
async def get_template_detail(
    template_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(ProductTemplate)
        .where(ProductTemplate.id == template_id, ProductTemplate.status == "approved")
        .options(
            selectinload(ProductTemplate.images),
            selectinload(ProductTemplate.variants),
            selectinload(ProductTemplate.collections),
        )
    )
    tpl = result.scalar_one_or_none()
    if not tpl:
        raise HTTPException(404, "模板不存在或未审核")
    return TemplateDetailOut(
        **{c.name: getattr(tpl, c.name) for c in ProductTemplate.__table__.columns},
        images=tpl.images, variants=tpl.variants,
        sources=[], collections=[CollectionBrief.model_validate(c) for c in tpl.collections],
    )


@router.post("/import", response_model=TemplateImportResult)
async def import_templates(
    body: TemplateImportRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(ProductTemplate)
        .where(
            ProductTemplate.id.in_(body.template_ids),
            ProductTemplate.status == "approved",
        )
        .options(
            selectinload(ProductTemplate.images),
            selectinload(ProductTemplate.variants),
        )
    )
    templates = result.scalars().unique().all()

    existing_skus_q = await db.execute(
        select(Product.sku).where(
            Product.tenant_id == current_user.tenant_id,
            Product.sku.in_([t.sku for t in templates]),
        )
    )
    existing_skus = set(existing_skus_q.scalars().all())

    imported = 0
    skipped = []

    for tpl in templates:
        if tpl.sku in existing_skus:
            skipped.append(tpl.sku)
            continue

        product = Product(
            tenant_id=current_user.tenant_id,
            source_template_id=tpl.id,
            name=tpl.name,
            name_en=tpl.name_en,
            sku=tpl.sku,
            slug=_slugify(tpl.name),
            description=tpl.description,
            description_en=tpl.description_en,
            ai_description=tpl.ai_description,
            ai_description_en=tpl.ai_description_en,
            base_price=tpl.base_price,
            cost_price=tpl.cost_price,
            market_price=tpl.market_price,
            weight=tpl.weight,
            length=tpl.length,
            width=tpl.width,
            height=tpl.height,
            extra_attributes=tpl.extra_attributes,
            meta_title=tpl.meta_title,
            meta_title_en=tpl.meta_title_en,
            meta_description=tpl.meta_description,
            meta_description_en=tpl.meta_description_en,
            seo_keywords=tpl.seo_keywords,
            seo_keywords_en=tpl.seo_keywords_en,
            status="draft",
            stock_qty=0,
        )
        db.add(product)
        await db.flush()

        for img in tpl.images:
            db.add(ProductImage(
                product_id=product.id,
                tenant_id=current_user.tenant_id,
                url=img.url,
                alt_text=img.alt_text,
                is_primary=img.is_primary,
                sort_order=img.sort_order,
            ))

        for var in tpl.variants:
            db.add(ProductVariant(
                product_id=product.id,
                tenant_id=current_user.tenant_id,
                sku=var.sku,
                attributes=var.attributes,
                price_modifier=var.price_modifier,
                independent_price=var.independent_price,
                weight=var.weight,
                is_default=var.is_default,
                stock_qty=0,
            ))

        imported += 1

    await db.commit()
    return TemplateImportResult(imported=imported, skipped_skus=skipped)
