import json
import logging
import os
from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException, Query, Request, UploadFile, File, status
from fastapi.responses import RedirectResponse
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

from app.config import settings
from app.dependencies import get_db, get_current_user
from app.models.user import User
from app.models.project import Project
from app.models.generation_record import GenerationRecord
from app.schemas.generation import (
    OptimizeParams,
    GenerateParams,
    GenerationRecordOut,
    GenerationRecordPageListOut,
    OptimizeResult,
    UpdatePromptRequest,
    GenerationType,
    DURATIONS,
    ASPECT_RATIOS,
    RESOLUTIONS,
    IMAGE_SIZES,
)
from app.services.credits import deduct_credits, calc_text_credits
from app.services.llm import optimize_prompt
from app.services.video_url import generate_temp_url, validate_and_get_record_id, get_video_stream_url
from app.services.resource_accounting_service import (
    record_generation_record_generated_resource,
    safe_file_size,
)
from app.services.resource_signed_url_service import build_resource_signed_url
from app.services.generation_billing_service import (
    CHARGE_TEXT_PROMPT,
    OWNER_GENERATION_RECORD,
    build_credit_biz_key,
    charge_generation_media_by_params,
    charge_generation_media_for_record,
    get_next_credit_attempt_no,
)
from app.services.generation_refund_service import mark_generation_record_failed_and_refund_once
from app.services.media_token_usage_snapshot_service import sync_generation_record_media_token_snapshot
from app.services.credit_record_meta_service import build_generation_record_prompt_meta
from app.services.video_cover_service import async_create_video_cover_for_local_video
from app.utils.id_gen import generate_id
from app.utils.exceptions import InsufficientCreditsError, RecordNotFoundError, InvalidStatusError

router = APIRouter(prefix="/generation-records", tags=["generation"])
logger = logging.getLogger("videogen")


def _record_to_out(record: GenerationRecord, project_name: str) -> GenerationRecordOut:
    refs = None
    if record.media_references:
        try:
            refs = json.loads(record.media_references)
        except (json.JSONDecodeError, TypeError):
            refs = None
    
    error_message = record.error_message
    if error_message:
        from app.services.error_codes import ARK_ERRORS
        import re
        match = re.search(r"code='([^']+)'", error_message)
        if match:
            code = match.group(1)
            if code in ARK_ERRORS:
                error_message = ARK_ERRORS[code]
        else:
            parts = error_message.split(":")
            if len(parts) >= 2 and parts[1].strip() in ARK_ERRORS:
                error_message = ARK_ERRORS[parts[1].strip()]
    
    return GenerationRecordOut(
        id=record.id,
        project_id=record.project_id,
        project_name=project_name,
        original_prompt=record.original_prompt,
        optimized_prompt=record.optimized_prompt,
        gen_type=record.gen_type,
        duration=record.duration,
        aspect_ratio=record.aspect_ratio,
        resolution=record.resolution,
        image_size=record.image_size,
        image_proportion=record.image_proportion,
        image_px=record.image_px,
        status=record.status,
        video_url=build_resource_signed_url(record.video_url) if record.video_url else '',
        video_cover_url=build_resource_signed_url(record.video_cover_url) if record.video_cover_url else '',
        image_url=build_resource_signed_url(record.image_url) if record.image_url else '',
        references=refs,
        text_credits_cost=round(record.text_credits_cost or 0.00, 2),
        # text_tokens_used=record.text_tokens_used or 0,
        credits_cost=round(record.credits_cost or 0.00, 2),
        # video_tokens_used=record.video_tokens_used or 0,
        # image_tokens_used=record.image_tokens_used or 0,
        error_message=error_message,
        created_at=record.created_at,
        generated_at=record.generated_at,
    )


@router.get("", response_model=GenerationRecordPageListOut)
async def list_records(
    project_id: str | None = Query(
        None,
        alias="project_id",
        description="查询单个项目的生成记录",
    ),
    status: str | None = Query(
        None,
        description="查询状态，可以不传。prompt_optimized:待生成 | generating:生成中 | failed:失败 | completed:成功",
        examples=["completed"],
    ),
    page: int = Query(
        1,
        ge=1,
        description="分页页码，从1开始",
        examples=[1],
    ),
    page_size: int = Query(
        10,
        ge=1,
        le=100,
        description="每页返回的生成记录数量，范围 1~100",
        examples=[10],
    ),
    record_ids: list[str] | None = Query(
        None,
        description="对应记录ID数组",
        examples=[["0019e8c55ddd1429b86", "0019e8c54dfc1e13262"]],
    ),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    allowed_statuses = {
        "prompt_optimized",
        "generating",
        "failed",
        "completed",
    }

    if status and status not in allowed_statuses:
        raise HTTPException(
            status_code=400,
            detail="状态参数错误，仅支持：prompt_optimized、generating、failed、completed",
        )

    offset = (page - 1) * page_size

    conditions = [
        GenerationRecord.user_id == current_user.id,
        GenerationRecord.deleted_at.is_(None),
        Project.deleted_at.is_(None),
    ]

    if project_id:
        conditions.append(GenerationRecord.project_id == project_id)

    if status:
        conditions.append(GenerationRecord.status == status)

    if record_ids:
        conditions.append(GenerationRecord.id.in_(record_ids))

    total_result = await db.execute(
        select(func.count(GenerationRecord.id))
        .join(Project, GenerationRecord.project_id == Project.id)
        .where(*conditions)
    )
    total = total_result.scalar_one() or 0

    query = (
        select(GenerationRecord, Project.name)
        .join(Project, GenerationRecord.project_id == Project.id)
        .where(*conditions)
        .order_by(GenerationRecord.created_at.desc())
        .offset(offset)
        .limit(page_size)
    )

    result = await db.execute(query)
    rows = result.all()

    return {
        "total": int(total),
        "page": page,
        "page_size": page_size,
        "items": [
            _record_to_out(record, project_name)
            for record, project_name in rows
        ],
    }

@router.post("/optimize", response_model=OptimizeResult)
async def optimize(
    req: OptimizeParams,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    record = None
    # Validate parameters based on generation type
    if req.gen_type == GenerationType.video:
        if req.duration not in DURATIONS:
            raise HTTPException(status_code=400, detail=f"视频时长必须为{DURATIONS}秒之一")
        if not req.duration:
            raise HTTPException(status_code=400, detail="视频生成需要指定时长")
    elif req.gen_type == GenerationType.image:
        if req.image_size not in IMAGE_SIZES:
            raise HTTPException(status_code=400, detail=f"图片分辨率必须为{IMAGE_SIZES}之一")
        if not req.image_size:
            raise HTTPException(status_code=400, detail="图片生成需要指定画面分辨率")

    # Idempotency check: if key provided, return existing record if found
    if req.idempotency_key:
        existing = await db.execute(
            select(GenerationRecord, Project.name)
            .join(Project, GenerationRecord.project_id == Project.id)
            .where(
                GenerationRecord.user_id == current_user.id,
                GenerationRecord.deleted_at.is_(None),
                Project.deleted_at.is_(None),
                GenerationRecord.idempotency_key == req.idempotency_key,
                GenerationRecord.gen_type == req.gen_type,
                GenerationRecord.status == "prompt_optimized",
            )
            .order_by(GenerationRecord.created_at.desc())
            .limit(1)
        )
        row = existing.first()
        if row:
            record, project_name = row
            return OptimizeResult(
                optimized_prompt=record.optimized_prompt or "",
                text_credits_cost=record.text_credits_cost or 0.00,
                text_tokens_used=record.text_tokens_used or 0,
                record=_record_to_out(record, project_name),
            )

    # Check project exists and belongs to user
    proj_result = await db.execute(
        select(Project).where(
            Project.id == req.project_id,
            Project.user_id == current_user.id,
            Project.deleted_at.is_(None),
        )
        .limit(1)
    )
    project = proj_result.scalar_one_or_none()
    if not project:
        raise HTTPException(status_code=404, detail="项目不存在")

    # Optimize prompt via LLM with type-specific context
    try:
        optimized, token_usage = await optimize_prompt(
            db, req.prompt,
            user_id=current_user.id, 
            industry_key=project.industry,
            duration=req.duration if req.gen_type == GenerationType.video else None,
            image_size=req.image_size if req.gen_type == GenerationType.image else None,
            image_proportion=req.image_proportion if req.gen_type == GenerationType.image else None,
            image_px=req.image_px if req.gen_type == GenerationType.image else None,
            references=req.references,
            gen_type=req.gen_type,
        )
        # Create record BEFORE LLM call so it's visible if user refreshes
        record = GenerationRecord(
            id=generate_id(),
            user_id=current_user.id,
            project_id=req.project_id,
            original_prompt=req.prompt,
            gen_type=req.gen_type,
            duration=req.duration,
            image_size=req.image_size,
            image_proportion=req.image_proportion,
            image_px=req.image_px,
            status="optimizing",
            credits_cost=0,
            text_credits_cost=0,
            text_tokens_used=0,
            media_references=json.dumps(req.references) if req.references else None,
            idempotency_key=req.idempotency_key,
        )
        db.add(record)
        await db.flush()
        await db.commit()
    except Exception as e:
        from app.services.error_codes import extract_error_message
        if record:
            record.status = "failed"
            record.error_message = extract_error_message(e, "提示词")
            await db.flush()
            await db.commit()
        error_message = extract_error_message(e, "提示词")
        raise HTTPException(
            status_code=502,
            detail=f"AI模型调用失败: {error_message}"
        )

    text_credits = await calc_text_credits(
        db, token_usage["input_tokens"], token_usage["output_tokens"],
    )

    failed_record_id = record.id
    failed_user_id = current_user.id
    try:
        prompt_attempt_no = 1
        prompt_biz_key = build_credit_biz_key(
            owner_type=OWNER_GENERATION_RECORD,
            owner_id=record.id,
            attempt_no=prompt_attempt_no,
            charge_kind=CHARGE_TEXT_PROMPT,
            action="charge",
        )
        prompt_meta = await build_generation_record_prompt_meta(
            db,
            record_id=record.id,
            attempt_no=prompt_attempt_no,
            charge_kind=CHARGE_TEXT_PROMPT,
            usage=token_usage,
        )
        await deduct_credits(
            db, current_user.id, text_credits,
            f"提示词优化 - {project.name}",
            related_id=record.id,
            biz_key=prompt_biz_key,
            record_meta=prompt_meta,
        )
    except InsufficientCreditsError as e:
        # /optimize 阶段只处理提示词优化扣费。
        # 提示词积分不足时，之前已落库的 optimizing 记录必须改为 failed，避免前端长期显示生成中。
        # 此阶段没有媒体生成扣费，不调用生成失败退款逻辑。
        await db.rollback()
        result = await db.execute(
            select(GenerationRecord)
            .where(
                GenerationRecord.id == failed_record_id,
                GenerationRecord.user_id == failed_user_id,
                GenerationRecord.deleted_at.is_(None),
            )
            .with_for_update()
            .limit(1)
        )
        failed_record = result.scalar_one_or_none()
        if failed_record:
            failed_record.status = "failed"
            failed_record.error_message = e.detail
            failed_record.optimized_prompt = None
            failed_record.text_credits_cost = 0
            failed_record.credits_cost = 0
            failed_record.text_tokens_used = token_usage.get("total_tokens", 0)
            await db.flush()
            # 这里必须主动提交，否则后续抛出 402 后 get_db 会 rollback，failed 状态会被回滚。
            await db.commit()
        raise e

    record.optimized_prompt = optimized
    record.status = "prompt_optimized"
    record.text_credits_cost = round(text_credits, 2)
    record.text_tokens_used = token_usage["total_tokens"]
    await db.flush()

    return OptimizeResult(
        optimized_prompt=optimized,
        text_credits_cost=round(text_credits, 2),
        # text_tokens_used=token_usage["total_tokens"],
        record=_record_to_out(record, project.name),
    )


@router.post("/{record_id}/generate")
async def generate(
    record_id: str,
    req: GenerateParams,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(
        select(GenerationRecord, Project.name)
        .join(Project, GenerationRecord.project_id == Project.id)
        .where(
            GenerationRecord.id == record_id,
            GenerationRecord.user_id == current_user.id,
            GenerationRecord.deleted_at.is_(None),
            Project.deleted_at.is_(None),
        )
        .with_for_update()
    )
    row = result.first()
    if not row:
        raise RecordNotFoundError()

    record, project_name = row
    if record.status not in ("prompt_optimized", "failed"):
        raise InvalidStatusError("当前状态不允许生成")

    attempt_no = await get_next_credit_attempt_no(
        db,
        owner_type=OWNER_GENERATION_RECORD,
        owner_id=record.id,
    )

    if record.gen_type == GenerationType.video:
        # Video generation
        if req.aspect_ratio not in ASPECT_RATIOS:
            raise HTTPException(status_code=400, detail="不支持的画面比例")
        if req.resolution not in RESOLUTIONS:
            raise HTTPException(status_code=400, detail="不支持的分辨率")

        duration = record.duration or 5
        media_billing = await charge_generation_media_by_params(
            db,
            user_id=current_user.id,
            record_id=record.id,
            gen_type="video",
            duration=duration,
            resolution=req.resolution,
            project_name=project_name,
            description_prefix=project_name+"-",
            owner_type=OWNER_GENERATION_RECORD,
            attempt_no=attempt_no,
        )

        record.aspect_ratio = req.aspect_ratio
        record.resolution = req.resolution
        record.credits_cost = round(float(record.credits_cost or 0) + media_billing.total_charged, 2)
        record.status = "generating"
        record.error_message = None
        record.video_url = None
        record.video_cover_url = None
        record.image_url = None
        record.seedance_task_id = None
        await db.flush()

        try:
            from app.services.video_gen import get_active_engine, submit_video_task
            from app.services.error_codes import extract_error_message
            from app.services.video_queue import task_queue

            engine = await get_active_engine(db)
            task_id = await submit_video_task(
                db,
                engine,
                record,
                include_media_references=False,
            )
            record.seedance_task_id = task_id
            await db.flush()
            await task_queue.enqueue(record_id)
        except Exception as e:
            await mark_generation_record_failed_and_refund_once(
                db,
                record=record,
                error_message=extract_error_message(e, "视频"),
            )
            await db.flush()

    elif record.gen_type == GenerationType.image:
        image_size = req.image_size or record.image_size or "2K"
        media_billing = await charge_generation_media_by_params(
            db,
            user_id=current_user.id,
            record_id=record.id,
            gen_type="image",
            image_size=image_size,
            project_name=project_name,
            description_prefix=project_name+"-",
            owner_type=OWNER_GENERATION_RECORD,
            attempt_no=attempt_no,
        )

        record.image_size = image_size
        record.credits_cost = round(float(record.credits_cost or 0) + media_billing.total_charged, 2)
        record.status = "generating"
        record.error_message = None
        record.image_url = None
        record.video_url = None
        record.video_cover_url = None
        record.seedance_task_id = None
        await db.flush()

        try:
            from app.services.video_queue import task_queue
            await task_queue.enqueue(record_id)
        except Exception as e:
            await mark_generation_record_failed_and_refund_once(
                db,
                record=record,
                error_message=f"图片任务队列投递失败: {e}",
            )
            await db.flush()

    return _record_to_out(record, project_name)


@router.post("/{record_id}/retry")
async def retry_generation(
    record_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(
        select(GenerationRecord, Project.name)
        .join(Project, GenerationRecord.project_id == Project.id)
        .where(
            GenerationRecord.id == record_id,
            GenerationRecord.user_id == current_user.id,
            GenerationRecord.deleted_at.is_(None),
            Project.deleted_at.is_(None),
        )
        .with_for_update()
    )
    row = result.first()
    if not row:
        raise RecordNotFoundError()

    record, project_name = row
    if record.status != "failed":
        raise InvalidStatusError("只有失败的记录可以重试")

    attempt_no = await get_next_credit_attempt_no(
        db,
        owner_type=OWNER_GENERATION_RECORD,
        owner_id=record.id,
    )
    media_billing = await charge_generation_media_for_record(
        db,
        record=record,
        project_name=project_name,
        description_prefix="视频重试",
        attempt_no=attempt_no,
    )

    record.status = "generating"
    record.error_message = None
    record.video_url = None
    record.video_cover_url = None
    record.image_url = None
    record.seedance_task_id = None
    record.generated_at = None
    record.credits_cost = round(float(record.credits_cost or 0) + media_billing.total_charged, 2)
    await db.flush()

    try:
        from app.services.video_queue import task_queue
        if record.gen_type == GenerationType.video:
            from app.services.video_gen import get_active_engine, submit_video_task, extract_error_message
            engine = await get_active_engine(db)
            task_id = await submit_video_task(
                db,
                engine,
                record,
                include_media_references=False,
            )
            record.seedance_task_id = task_id
            await db.flush()
        await task_queue.enqueue(record_id)
    except Exception as e:
        from app.services.error_codes import extract_error_message
        await mark_generation_record_failed_and_refund_once(
            db,
            record=record,
            error_message=extract_error_message(e, "重试"),
        )
        await db.flush()

    return _record_to_out(record, project_name)


@router.put("/{record_id}/prompt")
async def update_prompt(
    record_id: str,
    req: UpdatePromptRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(
        select(GenerationRecord).where(
            GenerationRecord.id == record_id,
            GenerationRecord.user_id == current_user.id,
            GenerationRecord.deleted_at.is_(None),
        )
        .limit(1)
    )
    record = result.scalar_one_or_none()
    if not record:
        raise RecordNotFoundError()
    if record.status != "prompt_optimized":
        raise InvalidStatusError("只有待生成状态可以修改提示词")

    record.optimized_prompt = req.optimized_prompt
    await db.flush()
    return {"message": "ok"}


@router.get("/{record_id}/video")
async def get_video(
    record_id: str,
    token: str = Query(...),
    db: AsyncSession = Depends(get_db),
):
    """Validate temp token and redirect to video URL."""
    validated_id = await validate_and_get_record_id(token)
    if validated_id != record_id:
        raise HTTPException(status_code=403, detail="无效的视频链接")

    video_url = await get_video_stream_url(db, record_id)
    if not video_url:
        raise HTTPException(status_code=404, detail="视频不存在")

    return RedirectResponse(url=video_url)


@router.get("/{record_id}/queue-status")
async def get_queue_status(
    record_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Get queue position, estimated wait time, and current status for a generation record."""
    from sqlalchemy import func

    result = await db.execute(
        select(GenerationRecord).where(
            GenerationRecord.id == record_id,
            GenerationRecord.user_id == current_user.id,
            GenerationRecord.deleted_at.is_(None),
        )
        .limit(1)
    )
    record = result.scalar_one_or_none()
    if not record:
        raise RecordNotFoundError()

    queue_position = None
    estimated_wait_seconds = None

    if record.status == "generating":
        ahead_result = await db.execute(
            select(func.count(GenerationRecord.id)).where(
                GenerationRecord.status == "generating",
                GenerationRecord.deleted_at.is_(None),
                GenerationRecord.created_at < record.created_at,
            )
        )
        ahead = ahead_result.scalar() or 0
        queue_position = ahead + 1
        estimated_wait_seconds = ahead * 60

    return {
        "record_id": record.id,
        "status": record.status,
        "queue_position": queue_position,
        "estimated_wait_seconds": estimated_wait_seconds,
    }


@router.post("/callbacks/seedance")
async def seedance_callback(request: Request, db: AsyncSession = Depends(get_db)):
    """Receive async callback from Seedance API."""
    data = await request.json()
    task_id = data.get("id")
    task_status = data.get("status")

    if not task_id:
        return {"message": "ignored"}

    result = await db.execute(
        select(GenerationRecord).where(
            GenerationRecord.seedance_task_id == task_id,
            GenerationRecord.deleted_at.is_(None),
        )
        .with_for_update()
        .limit(1)
    )
    record = result.scalar_one_or_none()
    if not record:
        return {"message": "record not found"}

    if task_status == "succeeded":
        remote_url = data.get("content", {}).get("video_url", "")
        record.status = "completed"
        storage_path = None
        file_size_bytes = 0
        # Download video to local storage
        if settings.STORAGE_TYPE == "local" and remote_url:
            try:
                from app.services.video_gen import download_video
                date_dir = datetime.now().strftime("%Y/%m/%d")
                dest_dir = os.path.join(settings.STORAGE_LOCAL_PATH, date_dir)
                os.makedirs(dest_dir, exist_ok=True)
                dest = os.path.join(dest_dir, f"{record.id}.mp4")
                await download_video(remote_url, dest)
                record.video_url = f"/generate/videos/{date_dir}/{record.id}.mp4"
                cover_url, _cover_storage_path = await async_create_video_cover_for_local_video(
                    record_id=record.id,
                    video_path=dest,
                    date_dir=date_dir,
                    log_prefix=f"SeedanceCallback视频封面生成 record_id={record.id}",
                )
                record.video_cover_url = cover_url
                storage_path = dest
                file_size_bytes = safe_file_size(dest)
            except Exception as e:
                logger.warning(f"Callback download failed, using remote URL: {e}")
                record.video_url = remote_url
        else:
            record.video_url = remote_url
        record.generated_at = datetime.now()
        if record.video_url:
            await record_generation_record_generated_resource(
                db,
                record,
                resource_url=record.video_url,
                storage_path=storage_path,
                file_size_bytes=file_size_bytes,
                remote_url=remote_url,
                generated_at=record.generated_at,
            )
        # Extract video token usage from callback
        usage = data.get("usage", {})
        if usage:
            record.video_tokens_used = usage.get("total_tokens", 0)
        await sync_generation_record_media_token_snapshot(db, record, provider_response=data)
        # Log callback response
        from app.services.video_gen import _log_video_response
        _log_video_response(record.id, data)
        # Notify user
        from app.services.notification import create_notification
        from app.api.v1.notifications import push_notification_to_user
        notif = await create_notification(
            db, record.user_id, "视频生成完成",
            "您的视频已生成完成，可以查看了。", "video", record.id,
        )
        await push_notification_to_user(record.user_id, notif)
    elif task_status == "failed":
        error_message = data.get("error", "视频生成失败")
        await mark_generation_record_failed_and_refund_once(
            db,
            record=record,
            error_message=error_message,
        )
        # Log callback response
        from app.services.video_gen import _log_video_response
        _log_video_response(record.id, data, error=record.error_message)
        # Notify user
        from app.services.notification import create_notification
        from app.api.v1.notifications import push_notification_to_user
        notif = await create_notification(
            db, record.user_id, "视频生成失败",
            f"视频生成失败：{record.error_message}", "video", record.id,
        )
        await push_notification_to_user(record.user_id, notif)

    await db.flush()
    return {"message": "ok"}


@router.post("/upload-image")
async def upload_image(
    file: UploadFile = File(...),
    current_user: User = Depends(get_current_user),
    gen_type: str = Query("video", description="生成类型：video-视频，image-图片"),
):
    """Upload an image for generation reference."""
    import os
    import uuid
    from app.config import settings
    from datetime import datetime

    if not file.content_type or not file.content_type.startswith("image/"):
        raise HTTPException(status_code=400, detail="仅支持图片文件")

    ext = os.path.splitext(file.filename or ".png")[1] or ".png"
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    safe_name = f"{gen_type}_img_{current_user.id}_{timestamp}_{uuid.uuid4().hex[:8]}{ext}"
    date_dir = datetime.now().strftime("%Y/%m/%d")
    dir_path = os.path.join(settings.UPLOAD_LOCAL_PATH, "images", date_dir)
    os.makedirs(dir_path, exist_ok=True)
    file_path = os.path.join(dir_path, safe_name)

    content = await file.read()
    if len(content) > 10 * 1024 * 1024:
        raise HTTPException(status_code=400, detail="图片大小不能超过10MB")

    with open(file_path, "wb") as f:
        f.write(content)

    url = f"/uploads/images/{date_dir}/{safe_name}"
    return {"url": url, "filename": file.filename or safe_name, "type": "image", "gen_type": gen_type}


@router.post("/upload-video")
async def upload_video(
    file: UploadFile = File(...),
    current_user: User = Depends(get_current_user),
):
    """Upload a video for generation reference."""
    import os
    import uuid
    from app.config import settings
    from datetime import datetime

    if not file.content_type or not file.content_type.startswith("video/"):
        raise HTTPException(status_code=400, detail="仅支持视频文件")

    ext = os.path.splitext(file.filename or ".mp4")[1] or ".mp4"
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    safe_name = f"video_ref_{current_user.id}_{timestamp}_{uuid.uuid4().hex[:8]}{ext}"
    date_dir = datetime.now().strftime("%Y/%m/%d")
    dir_path = os.path.join(settings.UPLOAD_LOCAL_PATH, "videos", date_dir)
    os.makedirs(dir_path, exist_ok=True)
    file_path = os.path.join(dir_path, safe_name)

    content = await file.read()
    if len(content) > 100 * 1024 * 1024:
        raise HTTPException(status_code=400, detail="视频大小不能超过100MB")

    with open(file_path, "wb") as f:
        f.write(content)

    url = f"/uploads/videos/{date_dir}/{safe_name}"
    return {"url": url, "filename": file.filename or safe_name, "type": "video"}


@router.post("/delete-file")
async def delete_upload(
    url: str = Query(..., description="文件URL，如 /uploads/images/2024/01/01/video_img_xxx.png"),
    current_user: User = Depends(get_current_user),
):
    """Delete an uploaded file by URL."""
    import os
    from app.config import settings

    if not url.startswith("/uploads/"):
        raise HTTPException(status_code=400, detail="无效的文件路径")

    if current_user.id not in url:
        raise HTTPException(status_code=403, detail="无权删除此文件")

    file_path = os.path.join(settings.UPLOAD_LOCAL_PATH, url.replace("/uploads/", ""))
    if os.path.exists(file_path):
        os.remove(file_path)

    return {"message": "ok"}
