from sqlalchemy import BigInteger, String, JSON, SmallInteger, Integer, Text, Index, ForeignKey
from sqlalchemy.dialects.mysql import DATETIME as MYSQL_DATETIME
from sqlalchemy.orm import Mapped, mapped_column
from app.core.models.base import Base, TimestampMixin


class AsyncTaskLog(Base, TimestampMixin):
    """
    异步任务日志（Celery 任务的持久化备份）
    Redis 崩溃时可从此表恢复未完成任务
    """

    __tablename__ = "async_task_logs"
    __table_args__ = (
        Index("ix_task_tenant", "tenant_id"),
        Index("ix_task_type", "task_type"),
        Index("ix_task_status", "status"),
        {
            "mysql_engine": "InnoDB",
            "mysql_charset": "utf8mb4",
            "mysql_collate": "utf8mb4_unicode_ci",
        },
    )

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
    tenant_id: Mapped[int | None] = mapped_column(
        BigInteger,
        ForeignKey("tenants.id", ondelete="SET NULL"),
        nullable=True,
        comment="NULL = 系统级任务",
    )
    task_type: Mapped[str] = mapped_column(
        String(100), nullable=False,
        comment="send_email / update_sitemap / push_erp / convert_webp"
    )
    status: Mapped[str] = mapped_column(
        String(20), nullable=False, default="pending",
        comment="pending / running / success / failed"
    )
    payload: Mapped[dict] = mapped_column(JSON, nullable=False, comment="任务参数")
    result: Mapped[dict | None] = mapped_column(JSON, nullable=True, comment="执行结果或错误信息")
    retry_count: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=0, comment="已重试次数")
    completed_at: Mapped[MYSQL_DATETIME | None] = mapped_column(MYSQL_DATETIME(fsp=3), nullable=True)

    def __repr__(self) -> str:
        return f"<AsyncTaskLog id={self.id} type={self.task_type!r} status={self.status!r}>"

class AiTaskItem(Base, TimestampMixin):
    __tablename__ = "ai_task_items"
    __table_args__ = (
        Index("ix_ai_task_items_task", "task_id"),
        Index("ix_ai_task_items_tenant_task", "tenant_id", "task_id"),
        Index("ix_ai_task_items_status", "status"),
        {
            "mysql_engine": "InnoDB",
            "mysql_charset": "utf8mb4",
            "mysql_collate": "utf8mb4_unicode_ci",
        },
    )

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
    task_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("async_task_logs.id", ondelete="CASCADE"), nullable=False)
    tenant_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
    product_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
    row_index: Mapped[int] = mapped_column(Integer, nullable=False)
    status: Mapped[str] = mapped_column(String(20), nullable=False, default="pending")
    source_row: Mapped[dict] = mapped_column(JSON, nullable=False)
    result_row: Mapped[dict | None] = mapped_column(JSON, nullable=True)
    error: Mapped[str | None] = mapped_column(Text, nullable=True)
