import enum
import uuid
from datetime import datetime, timezone
from typing import Any
from sqlalchemy import Column
from sqlalchemy.types import JSON
from sqlmodel import Field, SQLModel


def now_utc() -> datetime:
    return datetime.now(timezone.utc)


class VideoStatus(str, enum.Enum):
    imported = "imported"
    needs_metadata = "needs_metadata"
    ready_for_review = "ready_for_review"
    in_review = "in_review"
    needs_changes = "needs_changes"
    quality_failed = "quality_failed"
    needs_internal_fix = "needs_internal_fix"
    rejected = "rejected"
    approved = "approved"
    scheduled = "scheduled"
    publishing = "publishing"
    uploaded_to_tiktok_draft = "uploaded_to_tiktok_draft"
    uploaded_draft = "uploaded_draft"
    uploaded_private = "uploaded_private"
    published = "published"
    failed = "failed"
    archived = "archived"


class Provider(str, enum.Enum):
    tiktok = "tiktok"
    youtube = "youtube"


class JobStatus(str, enum.Enum):
    queued = "queued"
    running = "running"
    succeeded = "succeeded"
    failed = "failed"


class User(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    email: str = Field(index=True, unique=True)
    password_hash: str
    role: str = "admin"
    created_at: datetime = Field(default_factory=now_utc)


class PlatformAccount(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    provider: Provider = Field(index=True)
    display_name: str
    external_account_id: str | None = Field(default=None, index=True)
    avatar_url: str | None = None
    account_type: str | None = None
    scopes: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    encrypted_access_token: str | None = None
    encrypted_refresh_token: str | None = None
    token_expires_at: datetime | None = None
    status: str = "connected"
    is_default: bool = False
    last_successful_api_call: datetime | None = None
    last_error: str | None = None
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class AppSetting(SQLModel, table=True):
    key: str = Field(primary_key=True)
    value_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    updated_at: datetime = Field(default_factory=now_utc)


class VideoAsset(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    candidate_id: str = Field(index=True, unique=True)
    package_id: str | None = Field(default=None, index=True)
    source: str = "manual_upload"
    file_path: str
    original_file_name: str | None = None
    mime_type: str | None = None
    file_size: int = 0
    checksum: str = Field(index=True, unique=True)
    duration_sec: float | None = None
    width: int | None = None
    height: int | None = None
    fps: float | None = None
    aspect_ratio: str | None = None
    thumbnail_path: str | None = None
    external_youtube_id: str | None = Field(default=None, index=True)
    external_tiktok_id: str | None = Field(default=None, index=True)
    source_label: str | None = Field(default=None, index=True)
    is_demo: bool = Field(default=False, index=True)
    import_batch_label: str | None = Field(default=None, index=True)
    transcript: str | None = None
    script: str | None = None
    language: str | None = None
    working_title: str | None = None
    theme_key: str | None = None
    topic_id: str | None = Field(default=None, index=True)
    content_pillar: str | None = None
    series: str | None = None
    is_aigc: bool = True
    commercial_promotes_own_brand: bool = False
    commercial_promotes_third_party: bool = False
    quality_score: int | None = None
    hook_score: int | None = None
    status: VideoStatus = Field(default=VideoStatus.imported, index=True)
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class PostDraft(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str = Field(index=True, foreign_key="videoasset.id")
    provider: Provider = Field(index=True)
    platform_account_id: str | None = Field(default=None, foreign_key="platformaccount.id")
    title: str | None = None
    description: str | None = None
    caption: str | None = None
    hashtags_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    tags_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    category_id: str | None = None
    privacy_status: str | None = None
    scheduled_at: datetime | None = None
    metadata_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    external_post_id: str | None = Field(default=None, index=True)
    source_metadata_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    status: str = "draft"
    approved_at: datetime | None = None
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class MetadataVersion(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    post_draft_id: str = Field(index=True, foreign_key="postdraft.id")
    edited_by: str = "system"
    diff_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    snapshot_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    edited_at: datetime = Field(default_factory=now_utc)


class CreativeChange(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str | None = Field(default=None, foreign_key="videoasset.id", index=True)
    external_post_id: str | None = Field(default=None, foreign_key="externalpost.id", index=True)
    post_draft_id: str | None = Field(default=None, foreign_key="postdraft.id", index=True)
    topic_id: str | None = Field(default=None, foreign_key="theme.id", index=True)
    change_type: str = Field(default="other", index=True)
    before_text: str | None = None
    after_text: str | None = None
    change_note: str | None = None
    hypothesis: str | None = None
    changed_at: datetime = Field(default_factory=now_utc, index=True)
    created_by: str = "creator"
    source: str = Field(default="manual", index=True)


class ActivityEvent(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    entity_type: str = Field(index=True)
    entity_id: str = Field(index=True)
    event_type: str = Field(index=True)
    label: str
    payload_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=now_utc, index=True)
    created_by: str = "creator"


class ReviewDecision(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str = Field(index=True, foreign_key="videoasset.id")
    production_queue_item_id: str | None = Field(default=None, foreign_key="productionqueueitem.id", index=True)
    decision: str = Field(index=True)  # approved | rejected | needs_changes
    reason: str
    categories_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=now_utc, index=True)
    created_by: str = "creator"


class RevisionRequest(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str = Field(index=True, foreign_key="videoasset.id")
    production_queue_item_id: str | None = Field(default=None, foreign_key="productionqueueitem.id", index=True)
    requested_changes: str
    categories_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    status: str = Field(default="open", index=True)  # open | in_progress | resolved | rejected
    created_at: datetime = Field(default_factory=now_utc, index=True)
    created_by: str = "creator"


class PublishJob(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    post_draft_id: str = Field(index=True, foreign_key="postdraft.id")
    provider: Provider = Field(index=True)
    job_type: str
    status: JobStatus = JobStatus.queued
    external_publish_id: str | None = None
    external_post_id: str | None = None
    upload_url_redacted: str | None = None
    error_code: str | None = None
    error_message: str | None = None
    attempts: int = 0
    started_at: datetime | None = None
    finished_at: datetime | None = None
    created_at: datetime = Field(default_factory=now_utc)


class ApiCallLog(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    provider: str
    endpoint: str
    method: str
    status_code: int | None = None
    request_redacted_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    response_redacted_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    error_code: str | None = None
    created_at: datetime = Field(default_factory=now_utc)


class ContentPillar(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    name: str
    description: str | None = None
    target_audience: str | None = None
    priority: int = 0
    status: str = "active"


class Theme(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    pillar_id: str | None = Field(default=None, foreign_key="contentpillar.id")
    title: str
    description: str | None = None
    angle: str | None = None
    audience_pain: str | None = None
    promise: str | None = None
    examples: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    banned_claims: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    default_language: str = "en"
    status: str = "active"
    priority: int = 0
    performance_score: float = 0
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class Idea(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    topic_id: str | None = Field(default=None, foreign_key="theme.id", index=True)
    title: str
    short_explanation: str | None = None
    keywords: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    source_links: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    notes: str | None = None
    pillar: str | None = None
    series: str | None = None
    priority: int = 0
    status: str = Field(default="idea", index=True)
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class ContentScript(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    family_id: str | None = Field(default=None, foreign_key="theme.id", index=True)
    video_asset_id: str | None = Field(default=None, foreign_key="videoasset.id", index=True)
    package_id: str | None = Field(default=None, index=True)
    title: str
    hook: str | None = None
    script_text: str | None = None
    platform_caption: str | None = None
    youtube_title: str | None = None
    youtube_description: str | None = None
    status: str = Field(default="idea", index=True)
    source_path: str | None = None
    performance_summary_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class ImportLog(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    package_id: str | None = Field(default=None, index=True)
    folder_name: str | None = None
    status: str = Field(default="pending", index=True)
    video_asset_id: str | None = Field(default=None, foreign_key="videoasset.id")
    message: str | None = None
    error: str | None = None
    created_at: datetime = Field(default_factory=now_utc)


class Series(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    name: str
    description: str | None = None
    theme_id: str | None = Field(default=None, foreign_key="theme.id")
    format_template: str | None = None
    posting_frequency: str | None = None
    status: str = "active"


class HookTemplate(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    theme_id: str | None = Field(default=None, foreign_key="theme.id")
    text: str
    platform: str | None = None
    tone: str | None = None
    performance_score: float = 0


class CaptionTemplate(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    theme_id: str | None = Field(default=None, foreign_key="theme.id")
    platform: str
    template: str
    hashtags: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    cta: str | None = None


class HashtagSet(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    name: str
    platform: str
    tags: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    notes: str | None = None


class CreativeBrief(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    theme_id: str | None = Field(default=None, foreign_key="theme.id")
    title: str
    target_length_sec: int | None = None
    voice_style: str | None = None
    visual_style: str | None = None
    music_style: str | None = None
    script_constraints: str | None = None
    compliance_notes: str | None = None
    created_at: datetime = Field(default_factory=now_utc)


class AnalyticsImport(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    source: str
    provider: str
    file_name: str
    imported_at: datetime = Field(default_factory=now_utc)
    status: str = "pending"
    row_count: int = 0
    error_log: str | None = None


class AnalyticsSnapshot(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    platform_post_id: str | None = None
    provider: str
    account_id: str | None = None
    video_id: str | None = Field(default=None, foreign_key="videoasset.id")
    snapshot_at: datetime = Field(default_factory=now_utc)
    metrics_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))


class AnalyticsImportBatch(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    provider: Provider = Field(default=Provider.youtube, index=True)
    account_id: str | None = Field(default=None, foreign_key="platformaccount.id", index=True)
    source_type: str = Field(default="youtube_csv", index=True)
    imported_at: datetime = Field(default_factory=now_utc, index=True)
    snapshot_at: datetime = Field(default_factory=now_utc, index=True)
    date_range_start: datetime | None = None
    date_range_end: datetime | None = None
    status: str = Field(default="pending", index=True)
    total_files: int = 0
    total_rows: int = 0
    warnings_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    errors_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    source_label: str | None = Field(default=None, index=True)
    is_demo: bool = Field(default=False, index=True)
    import_batch_label: str | None = Field(default=None, index=True)


class AnalyticsImportFile(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    batch_id: str = Field(index=True, foreign_key="analyticsimportbatch.id")
    file_name: str
    file_hash: str = Field(index=True)
    detected_type: str = Field(default="unknown", index=True)
    row_count: int = 0
    imported_rows: int = 0
    skipped_rows: int = 0
    status: str = Field(default="pending", index=True)
    warnings_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    errors_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=now_utc)


class ExternalPost(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    provider: Provider = Field(default=Provider.youtube, index=True)
    external_post_id: str = Field(index=True)
    account_id: str | None = Field(default=None, foreign_key="platformaccount.id", index=True)
    video_asset_id: str | None = Field(default=None, foreign_key="videoasset.id", index=True)
    title: str | None = None
    published_at: datetime | None = None
    duration_sec: int | None = None
    topic_id: str | None = Field(default=None, foreign_key="theme.id", index=True)
    series: str | None = None
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)
    source_label: str | None = Field(default=None, index=True)
    is_demo: bool = Field(default=False, index=True)
    import_batch_label: str | None = Field(default=None, index=True)
    source_file_name: str | None = Field(default=None, index=True)
    mapping_status: str = Field(default="open", index=True)
    ignored_at: datetime | None = None
    ignore_reason: str | None = None


class AnalyticsDailyAggregate(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    batch_id: str = Field(index=True, foreign_key="analyticsimportbatch.id")
    provider: Provider = Field(default=Provider.youtube, index=True)
    account_id: str | None = Field(default=None, foreign_key="platformaccount.id", index=True)
    metric_date: datetime = Field(index=True)
    views: int | None = None
    raw_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))


class AnalyticsPostSnapshot(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    batch_id: str = Field(index=True, foreign_key="analyticsimportbatch.id")
    provider: Provider = Field(default=Provider.youtube, index=True)
    account_id: str | None = Field(default=None, foreign_key="platformaccount.id", index=True)
    external_post_id: str = Field(index=True)
    video_asset_id: str | None = Field(default=None, foreign_key="videoasset.id", index=True)
    snapshot_at: datetime = Field(default_factory=now_utc, index=True)
    title: str | None = None
    published_at: datetime | None = None
    duration_sec: int | None = None
    views: int | None = None
    watch_time_hours: float | None = None
    subscribers_delta: int | None = None
    impressions: int | None = None
    impression_ctr_pct: float | None = None
    avg_view_duration_sec: float | None = None
    retention_proxy_pct: float | None = None
    views_per_impression: float | None = None
    subscribers_per_1000_views: float | None = None
    views_per_day_since_publish: float | None = None
    views_delta: int | None = None
    views_delta_pct: float | None = None
    views_velocity_per_day: float | None = None
    watch_time_delta: float | None = None
    impressions_delta: int | None = None
    subscriber_delta_change: int | None = None
    ctr_change: float | None = None
    retention_proxy_change: float | None = None
    days_since_previous_snapshot: float | None = None
    trend: str | None = None
    raw_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    source_label: str | None = Field(default=None, index=True)
    is_demo: bool = Field(default=False, index=True)
    import_batch_label: str | None = Field(default=None, index=True)
    source_file_name: str | None = Field(default=None, index=True)


class WebsiteCompanion(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str = Field(index=True, foreign_key="videoasset.id")
    post_draft_id: str | None = Field(default=None, foreign_key="postdraft.id", index=True)
    content_script_id: str | None = Field(default=None, foreign_key="contentscript.id", index=True)
    website_repo_path: str | None = None
    website_branch: str = "website-mvp-v0"
    slug: str | None = Field(default=None, index=True)
    title: str | None = None
    youtube_video_id: str | None = Field(default=None, index=True)
    video_url_internal: str | None = None
    website_link_allowed: bool = False
    candidate_payload_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    generated_content_path: str | None = None
    generated_thumbnail_path: str | None = None
    status: str = Field(default="not_started", index=True)
    last_error: str | None = None
    qa_status_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    git_status_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    duplicate_status_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class UploadExecutor(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    name: str
    type: str = Field(index=True)  # dashboard_oauth | existing_jarvis_uploader | dry_run | imported_existing
    status: str = Field(default="active", index=True)
    description: str | None = None
    config_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class UploadRequest(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str = Field(index=True, foreign_key="videoasset.id")
    post_draft_id: str = Field(index=True, foreign_key="postdraft.id")
    executor_type: str = Field(default="existing_jarvis_uploader", index=True)
    status: str = Field(default="draft", index=True)
    approval_text: str | None = None
    approval_command: str | None = None
    expected_candidate_id: str | None = Field(default=None, index=True)
    expected_video_sha: str | None = Field(default=None, index=True)
    expected_privacy: str = "private"
    metadata_snapshot_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    outbox_path: str | None = None
    upload_audit_id: str | None = Field(default=None, index=True)
    youtube_video_id: str | None = Field(default=None, index=True)
    created_at: datetime = Field(default_factory=now_utc)
    approved_at: datetime | None = None
    sent_at: datetime | None = None
    completed_at: datetime | None = None
    updated_at: datetime = Field(default_factory=now_utc)
    error: str | None = None


class ProductionQueueItem(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    family_id: str | None = Field(default=None, foreign_key="theme.id", index=True)
    idea_id: str | None = Field(default=None, foreign_key="idea.id", index=True)
    content_script_id: str | None = Field(default=None, foreign_key="contentscript.id", index=True)
    title: str
    brief: str | None = None
    script_constraints: str | None = None
    visual_constraints: str | None = None
    voice_constraints: str | None = None
    reason: str | None = None
    priority: int = 0
    position: int = Field(default=0, index=True)
    status: str = Field(default="suggested", index=True)
    source: str = Field(default="manual", index=True)
    expected_package_id: str | None = Field(default=None, index=True)
    expected_package_manifest: str | None = None
    actual_package_id: str | None = Field(default=None, index=True)
    video_asset_id: str | None = Field(default=None, foreign_key="videoasset.id", index=True)
    attached_package_path: str | None = None
    error: str | None = None
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class YouTubeUploadAudit(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str = Field(index=True, foreign_key="videoasset.id")
    post_draft_id: str = Field(index=True, foreign_key="postdraft.id")
    platform_account_id: str = Field(index=True, foreign_key="platformaccount.id")
    publish_job_id: str | None = Field(default=None, foreign_key="publishjob.id", index=True)
    youtube_video_id: str | None = Field(default=None, index=True)
    youtube_url: str | None = None
    privacy_status: str = "private"
    title: str | None = None
    description_hash: str | None = None
    tags_json: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    category_id: str | None = None
    contains_synthetic_media: bool = True
    self_declared_made_for_kids: bool = False
    notify_subscribers: bool = False
    upload_status: str = Field(default="queued", index=True)
    api_endpoints_called: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    oauth_scopes_used: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    website_link_allowed: bool = False
    request_redacted_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    response_redacted_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    error_code: str | None = None
    error_message: str | None = None
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class TikTokUploadAttempt(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    video_asset_id: str = Field(index=True, foreign_key="videoasset.id")
    post_draft_id: str = Field(index=True, foreign_key="postdraft.id")
    platform_account_id: str | None = Field(default=None, foreign_key="platformaccount.id", index=True)
    mode: str = Field(default="mock", index=True)  # mock | sandbox | real_disabled
    scope: str = Field(default="video.upload", index=True)
    source: str = Field(default="FILE_UPLOAD", index=True)
    publish_id: str | None = Field(default=None, index=True)
    upload_status: str = Field(default="created", index=True)
    transfer_status: str | None = Field(default=None, index=True)
    status_fetch_result_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    request_redacted_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    response_redacted_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    error_code: str | None = None
    error_message: str | None = None
    created_at: datetime = Field(default_factory=now_utc)
    updated_at: datetime = Field(default_factory=now_utc)


class MetricDefinition(SQLModel, table=True):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    key: str = Field(index=True, unique=True)
    display_name: str
    unit: str | None = None
    higher_is_better: bool = True
