# backend/app/plugins/contact_forms/store_router.py
import os
import uuid

from fastapi import APIRouter, Depends, File, Form, HTTPException, Request, UploadFile
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, get_tenant_by_domain
from app.core.services.plugin_helper import require_plugin
from app.services.email import build_smtp_config


async def _guard(
    tid: int = Depends(get_tenant_by_domain),
    db: AsyncSession = Depends(get_db),
) -> None:
    await require_plugin("contact_forms", db, tid)


store_router = APIRouter(
    prefix="/store/contact-forms",
    tags=["contact_forms_store"],
    dependencies=[Depends(_guard)],
)


@store_router.get("/{form_id}")
async def get_public_form(
    form_id: int,
    tid: int = Depends(get_tenant_by_domain),
    db: AsyncSession = Depends(get_db),
):
    from app.plugins.contact_forms.services import get_form_with_fields
    from app.plugins.contact_forms.schemas import ContactFormPublicOut

    form = await get_form_with_fields(db, form_id, tid)
    if not form or not form.is_active:
        raise HTTPException(404, "表单不存在")
    return ContactFormPublicOut.model_validate(form)


@store_router.post("/{form_id}/submit", status_code=201)
async def submit_form(
    form_id: int,
    body: dict,
    request: Request,
    tid: int = Depends(get_tenant_by_domain),
    db: AsyncSession = Depends(get_db),
):
    from app.core.models import ContactFormSubmission
    from app.core.models.tenant_settings import TenantSettings
    from app.plugins.contact_forms.schemas import ContactFormSubmissionIn
    from app.plugins.contact_forms.services import (
        get_form_with_fields, extract_submitter_info, send_form_emails
    )

    form = await get_form_with_fields(db, form_id, tid)
    if not form or not form.is_active:
        raise HTTPException(404, "表单不存在或已停用")

    sub_data = ContactFormSubmissionIn(**body)
    submitter_email, submitter_name = extract_submitter_info(sub_data.data, form.fields)
    ip = request.client.host if request.client else None

    submission = ContactFormSubmission(
        form_id=form_id,
        tenant_id=form.tenant_id,
        data=sub_data.data,
        submitter_email=submitter_email,
        submitter_name=submitter_name,
        ip_address=ip,
        status="unread",
    )
    db.add(submission)
    await db.commit()
    await db.refresh(submission)

    r = await db.execute(
        select(TenantSettings).where(TenantSettings.tenant_id == form.tenant_id)
    )
    smtp_config = build_smtp_config(r.scalar_one_or_none())
    await send_form_emails(db, form, submission, smtp_config)

    return {"success": True, "message": form.success_message}


@store_router.post("/{form_id}/upload")
async def upload_form_file(
    form_id: int,
    field_name: str = Form(...),
    file: UploadFile = File(...),
    tid: int = Depends(get_tenant_by_domain),
    db: AsyncSession = Depends(get_db),
):
    from app.api.routers.upload import (
        ALLOWED_TYPES,
        ATTACHMENT_ALLOWED_TYPES,
        ATTACHMENT_MAX_SIZE,
        ATTACHMENT_SAFE_EXT,
        MAX_SIZE,
        MIME_MAP,
        _consume_quota_and_get_storage,
        _refund_quota,
        _safe_attachment_ext,
        _safe_ext,
        _to_webp,
        _PIL_OK,
    )
    from app.core.services.storage_quota import mb_from_bytes
    from app.core.storage import check_storage_deps
    from app.plugins.contact_forms.services import get_form_with_fields

    form = await get_form_with_fields(db, form_id, tid)
    if not form or not form.is_active:
        raise HTTPException(404, "表单不存在或已停用")

    target_field = next((f for f in form.fields if f.name == field_name), None)
    if not target_field or target_field.field_type != "file":
        raise HTTPException(400, "无效的文件字段")

    content_type = (file.content_type or "").lower()
    original_ext = os.path.splitext(os.path.basename(file.filename or ""))[1].lower()
    is_image = content_type in ALLOWED_TYPES
    is_attachment = content_type in ATTACHMENT_ALLOWED_TYPES or original_ext in ATTACHMENT_SAFE_EXT
    if not is_image and not is_attachment:
        raise HTTPException(status_code=400, detail="Only image, PDF, Word, Excel, CSV, or TXT files allowed")

    content = await file.read()
    max_size = MAX_SIZE if is_image else ATTACHMENT_MAX_SIZE
    if len(content) > max_size:
        if not is_image:
            raise HTTPException(status_code=400, detail=f"Attachment must be under {ATTACHMENT_MAX_SIZE // 1024 // 1024}MB")
        raise HTTPException(status_code=400, detail="Image must be under 5MB")

    if is_image and _PIL_OK:
        try:
            content = _to_webp(content)
            ext = ".webp"
        except Exception:
            ext = _safe_ext(file.filename or "")
    elif is_image:
        ext = _safe_ext(file.filename or "")
    else:
        ext = _safe_attachment_ext(file.filename or "")

    folder = "contact_forms"
    filename = f"tenant_{tid}/{folder}/{form_id}/{uuid.uuid4().hex}{ext}"
    incoming_mb = mb_from_bytes(len(content))
    storage, profile = await _consume_quota_and_get_storage(db, tid, incoming_mb)

    provider = profile.provider if profile else "local"
    dep = check_storage_deps(provider)
    if not dep["ok"]:
        raise HTTPException(status_code=501, detail=f"CDN storage dependency missing: {dep['missing']}")

    try:
        stored_content_type = "image/webp" if ext == ".webp" else MIME_MAP.get(ext, content_type or "application/octet-stream")
        url = await storage.save(filename, content, content_type=stored_content_type)
    except Exception as e:
        await _refund_quota(db, tid, incoming_mb)
        raise HTTPException(status_code=502, detail=f"存储写入失败：{e}")

    return {
        "url": url,
        "filename": filename,
        "original_name": file.filename or "",
        "mime_type": MIME_MAP.get(ext, content_type),
        "file_size": len(content),
    }
