"""
AWOOOI 測試資料工廠
===================
為整合測試提供標準化測試資料建構函式
使用真實 ORM 模型，直接寫入真實 DB

原則:
- 不使用 Mock — 資料直接寫入真實 DB
- 透過 ORM 模型確保欄位型別正確
- 每個 factory 回傳 ORM 物件

2026-04-10 Claude Sonnet 4.6 Asia/Taipei
"""
from __future__ import annotations

import uuid
from datetime import datetime, timedelta, timezone

from sqlalchemy.ext.asyncio import AsyncSession

from src.db.models import ApprovalRecord, KnowledgeEntryRecord

TAIPEI = timezone(timedelta(hours=8))


def _now() -> datetime:
    return datetime.now(tz=TAIPEI)


def _uuid() -> str:
    return str(uuid.uuid4())


def _inc_id() -> str:
    """生成符合 INC-YYYYMMDD-XXXXXX 格式的 incident_id"""
    now = datetime.now(tz=TAIPEI)
    suffix = uuid.uuid4().hex[:6].upper()
    return f"INC-{now.strftime('%Y%m%d')}-{suffix}"


# =============================================================================
# Approval Factory
# =============================================================================

async def create_approval(
    session: AsyncSession,
    *,
    action: str = "RESTART_POD",
    description: str = "Test approval for integration testing",
    risk_level: str = "MEDIUM",
    status: str = "PENDING",
    requested_by: str = "test-system",
) -> ApprovalRecord:
    """建立測試 ApprovalRecord，回傳 ORM 物件"""
    record = ApprovalRecord(
        id=_uuid(),
        action=action,
        description=description,
        risk_level=risk_level,
        status=status,
        required_signatures=1,
        current_signatures=0,
        signatures=[],
        blast_radius={},
        dry_run_checks=[],
        requested_by=requested_by,
        extra_metadata={},
        hit_count=1,
        created_at=_now(),
        updated_at=_now(),
    )
    session.add(record)
    await session.flush()
    return record


# =============================================================================
# Knowledge Entry Factory
# =============================================================================

async def create_knowledge_entry(
    session: AsyncSession,
    *,
    title: str = "Test Entry",
    content: str = "Test content for integration testing",
    category: str = "test",
    entry_type: str = "RUNBOOK",
    status: str = "DRAFT",
    tags: list[str] | None = None,
    created_by: str = "test",
) -> KnowledgeEntryRecord:
    """建立測試知識條目"""
    entry = KnowledgeEntryRecord(
        id=_uuid(),
        title=title,
        content=content,
        category=category,
        entry_type=entry_type,
        status=status,
        tags=tags or [],
        source="HUMAN",
        view_count=0,
        created_by=created_by,
        created_at=_now(),
        updated_at=_now(),
    )
    session.add(entry)
    await session.flush()
    return entry


# =============================================================================
# Incident Factory (raw SQL — 結構複雜)
# =============================================================================

async def create_incident(
    session: AsyncSession,
    *,
    anomaly_type: str = "pod_crash",
    host: str = "mon",
    severity: str = "P1",
    status: str = "INVESTIGATING",
) -> dict:
    """建立測試 Incident，回傳包含 incident_id 的 dict"""
    from sqlalchemy import text

    incident_id = _inc_id()
    signals_json = f'[{{"type":"{anomaly_type}","host":"{host}","severity":"{severity}"}}]'

    await session.execute(
        text("""
            INSERT INTO incidents
                (incident_id, status, severity, signals, affected_services,
                 decision_chain, proposal_ids, outcome, created_at, updated_at, ttl_days, vectorized)
            VALUES
                (:id, CAST(:status AS incidentstatus), CAST(:severity AS severity),
                 CAST(:signals AS json), CAST(:aff AS json),
                 CAST(:dc AS json), CAST(:pids AS json), CAST(:outcome AS json),
                 :now, :now, 30, false)
        """),
        {
            "id": incident_id,
            "status": status,
            "severity": severity,
            "signals": signals_json,
            "aff": "[]",
            "dc": "[]",
            "pids": "[]",
            "outcome": "{}",
            "now": _now(),
        },
    )
    await session.flush()
    return {"incident_id": incident_id, "status": status, "severity": severity}


# =============================================================================
# RAG Chunk Factory (raw SQL — vector extension 依賴)
# =============================================================================

async def create_rag_chunk(
    session: AsyncSession,
    *,
    source: str = "test",
    source_id: str | None = None,
    title: str = "Test Document",
    chunk_text: str = "This is a test chunk for integration testing.",
) -> dict:
    """建立 RAG chunk (無 embedding)"""
    from sqlalchemy import text

    chunk_id = _uuid()
    sid = source_id or f"test-{_uuid()[:8]}"
    await session.execute(
        text("""
            INSERT INTO rag_chunks (id, source, source_id, title, chunk_text, metadata, created_at)
            VALUES (:id, :src, :sid, :title, :text, '{}'::jsonb, :now)
        """),
        {
            "id": chunk_id,
            "src": source,
            "sid": sid,
            "title": title,
            "text": chunk_text,
            "now": _now(),
        },
    )
    await session.flush()
    return {"id": chunk_id, "source": source, "source_id": sid}
