# #region Test.Models.Translate [C:2] [TYPE Module] [SEMANTICS test,models,translate,sqlalchemy]
# @BRIEF Tests for models/translate.py — TranslationJob, TranslationRun, TranslationBatch,
#        TranslationRecord, TranslationEvent, TranslationPreviewSession,
#        TranslationPreviewRecord, TerminologyDictionary, DictionaryEntry,
#        TranslationSchedule, TranslationJobDictionary, MetricSnapshot,
#        TranslationLanguage, TranslationPreviewLanguage, TranslationRunLanguageStats.
# @RELATION BINDS_TO -> [TranslateModels]
# @TEST_EDGE: generate_uuid -> returns a UUID string
# @TEST_EDGE: table_names -> all model tables registered
# @TEST_EDGE: columns_exist -> key column defaults and nullable config

import pytest
from datetime import datetime, timezone


class TestGenerateUuid:
    """generate_uuid helper in translate.py."""

    def test_returns_string(self):
        from src.models.translate import generate_uuid

        uid = generate_uuid()
        assert isinstance(uid, str)
        assert len(uid) > 20

    def test_unique(self):
        from src.models.translate import generate_uuid

        uids = {generate_uuid() for _ in range(50)}
        assert len(uids) == 50


class TestTranslationJob:
    """TranslationJob — main job table."""

    def test_table_name(self):
        from src.models.translate import TranslationJob

        assert TranslationJob.__tablename__ == "translation_jobs"

    def test_minimal_columns(self):
        from src.models.translate import TranslationJob

        obj = TranslationJob(name="Test Job", source_dialect="postgresql", target_dialect="clickhouse")
        assert obj.name == "Test Job"
        assert obj.source_dialect == "postgresql"
        assert obj.target_dialect == "clickhouse"
        # SQLAlchemy Column(default=...) only applies on INSERT via session, not at instance creation
        assert obj.status is None
        assert obj.batch_size is None
        assert obj.disable_reasoning is None
        assert obj.insert_method is None

    def test_with_all_columns(self):
        from src.models.translate import TranslationJob

        obj = TranslationJob(
            id="tj-2", name="Full Job", description="Test",
            source_dialect="postgresql", target_dialect="clickhouse",
            database_dialect="postgresql", status="ACTIVE",
            source_datasource_id="ds-1", source_table="orders",
            target_schema="public", target_table="orders_translated",
            source_key_cols=["id"], target_key_cols=["id"],
            translation_column="name", target_column="name_translated",
            target_language_column="lang", target_source_column="source_text",
            target_source_language_column="source_lang",
            context_columns=["category"], target_languages=["ru", "en"],
            provider_id="prov-1", batch_size=100, disable_reasoning=True,
            upsert_strategy="INSERT", environment_id="env-1",
            target_database_id="db-1", insert_method="direct_db",
            connection_id="conn-1", created_by="admin",
        )
        assert obj.source_datasource_id == "ds-1"
        assert obj.batch_size == 100
        assert obj.disable_reasoning is True
        assert obj.upsert_strategy == "INSERT"
        assert obj.insert_method == "direct_db"
        assert obj.connection_id == "conn-1"

    def test_defaults(self):
        from src.models.translate import TranslationJob

        obj = TranslationJob(name="J", source_dialect="pg", target_dialect="ch")
        assert obj.created_by is None
        # SQLAlchemy Column(default=...) only applies on INSERT via session
        assert obj.created_at is None
        assert obj.updated_at is None
        assert obj.target_languages is None
        assert obj.provider_id is None
        assert obj.description is None
        assert obj.source_table is None


class TestTranslationRun:
    """TranslationRun — execution run table."""

    def test_table_name(self):
        from src.models.translate import TranslationRun

        assert TranslationRun.__tablename__ == "translation_runs"

    def test_minimal(self):
        from src.models.translate import TranslationRun

        obj = TranslationRun(id="tr-1", job_id="job-1", status="PENDING")
        assert obj.id == "tr-1"
        assert obj.job_id == "job-1"
        assert obj.status == "PENDING"

    def test_with_fields(self):
        from src.models.translate import TranslationRun

        obj = TranslationRun(
            id="tr-2", job_id="job-1", status="RUNNING",
            trigger_type="manual", total_records=100,
            successful_records=80, failed_records=10,
            skipped_records=10, cache_hits=5,
            created_by="admin",
        )
        assert obj.trigger_type == "manual"
        assert obj.total_records == 100
        assert obj.cache_hits == 5


class TestTranslationBatch:
    """TranslationBatch — batch grouping table."""

    def test_table_name(self):
        from src.models.translate import TranslationBatch

        assert TranslationBatch.__tablename__ == "translation_batches"

    def test_minimal(self):
        from src.models.translate import TranslationBatch

        obj = TranslationBatch(id="tb-1", run_id="run-1", batch_index=0, status="PENDING")
        assert obj.id == "tb-1"
        assert obj.run_id == "run-1"
        assert obj.batch_index == 0
        assert obj.status == "PENDING"


class TestTranslationRecord:
    """TranslationRecord — individual translation result table."""

    def test_table_name(self):
        from src.models.translate import TranslationRecord

        assert TranslationRecord.__tablename__ == "translation_records"

    def test_minimal(self):
        from src.models.translate import TranslationRecord

        obj = TranslationRecord(id="trec-1", batch_id="b-1", run_id="run-1", status="PENDING")
        assert obj.id == "trec-1"
        assert obj.batch_id == "b-1"
        assert obj.status == "PENDING"

    def test_with_fields(self):
        from src.models.translate import TranslationRecord

        obj = TranslationRecord(
            id="trec-2", batch_id="b-1", run_id="run-1",
            source_sql="SELECT * FROM t", target_sql="SELECT * FROM t",
            source_object_type="query", source_object_id="q-1",
            status="SUCCESS", token_count_input=100, token_count_output=50,
        )
        assert obj.source_sql == "SELECT * FROM t"
        assert obj.target_sql == "SELECT * FROM t"
        assert obj.token_count_input == 100

    def test_languages_relationship(self):
        from src.models.translate import TranslationRecord

        assert hasattr(TranslationRecord, "languages")

    def test_table_args(self):
        from src.models.translate import TranslationRecord

        assert hasattr(TranslationRecord, "__table_args__")


class TestTranslationEvent:
    """TranslationEvent — audit event log."""

    def test_table_name(self):
        from src.models.translate import TranslationEvent

        assert TranslationEvent.__tablename__ == "translation_events"

    def test_minimal(self):
        from src.models.translate import TranslationEvent

        obj = TranslationEvent(id="te-1", job_id="j-1", event_type="JOB_CREATED")
        assert obj.id == "te-1"
        assert obj.job_id == "j-1"
        assert obj.event_type == "JOB_CREATED"
        assert obj.run_id is None


class TestTranslationPreviewSession:
    """TranslationPreviewSession — preview session."""

    def test_table_name(self):
        from src.models.translate import TranslationPreviewSession

        assert TranslationPreviewSession.__tablename__ == "translation_preview_sessions"

    def test_minimal(self):
        from src.models.translate import TranslationPreviewSession

        obj = TranslationPreviewSession(id="tps-1", job_id="j-1", status="ACTIVE")
        assert obj.id == "tps-1"
        assert obj.job_id == "j-1"
        assert obj.status == "ACTIVE"


class TestTranslationPreviewRecord:
    """TranslationPreviewRecord — individual preview entry."""

    def test_table_name(self):
        from src.models.translate import TranslationPreviewRecord

        assert TranslationPreviewRecord.__tablename__ == "translation_preview_records"

    def test_minimal(self):
        from src.models.translate import TranslationPreviewRecord

        obj = TranslationPreviewRecord(id="tpr-1", session_id="s-1", status="PENDING")
        assert obj.id == "tpr-1"
        assert obj.session_id == "s-1"
        assert obj.status == "PENDING"

    def test_languages_relationship(self):
        from src.models.translate import TranslationPreviewRecord

        assert hasattr(TranslationPreviewRecord, "languages")


class TestTerminologyDictionary:
    """TerminologyDictionary — dictionary collection."""

    def test_table_name(self):
        from src.models.translate import TerminologyDictionary

        assert TerminologyDictionary.__tablename__ == "terminology_dictionaries"

    def test_minimal(self):
        from src.models.translate import TerminologyDictionary

        obj = TerminologyDictionary(id="td-1", name="My Dict", is_active=True)
        assert obj.id == "td-1"
        assert obj.name == "My Dict"
        assert obj.is_active is True


class TestDictionaryEntry:
    """DictionaryEntry — individual term mapping."""

    def test_table_name(self):
        from src.models.translate import DictionaryEntry

        assert DictionaryEntry.__tablename__ == "dictionary_entries"

    def test_minimal(self):
        from src.models.translate import DictionaryEntry

        obj = DictionaryEntry(
            id="de-1", dictionary_id="d-1",
            source_term="hello", source_term_normalized="hello",
            target_term="привет", source_language="en", target_language="ru",
            has_context=False, is_regex=False,
        )
        assert obj.id == "de-1"
        assert obj.source_term == "hello"
        assert obj.target_term == "привет"

    def test_unique_constraint(self):
        from src.models.translate import DictionaryEntry

        assert hasattr(DictionaryEntry, "__table_args__")

    def test_with_all_fields(self):
        from src.models.translate import DictionaryEntry

        obj = DictionaryEntry(
            id="de-2", dictionary_id="d-1",
            source_term="hello", source_term_normalized="hello",
            target_term="привет", source_language="en", target_language="ru",
            context_notes="Greeting", context_data={"formality": "informal"},
            usage_notes="Use for casual greetings", has_context=True,
            is_regex=False, context_source="manual",
            origin_source_language="en", origin_run_id="run-1",
        )
        assert obj.context_data == {"formality": "informal"}
        assert obj.has_context is True


class TestTranslationSchedule:
    """TranslationSchedule — cron schedule."""

    def test_table_name(self):
        from src.models.translate import TranslationSchedule

        assert TranslationSchedule.__tablename__ == "translation_schedules"

    def test_minimal(self):
        from src.models.translate import TranslationSchedule

        obj = TranslationSchedule(
            id="ts-1", job_id="j-1", cron_expression="0 0 * * *",
            timezone="UTC", is_active=True, execution_mode="full",
        )
        assert obj.id == "ts-1"
        assert obj.cron_expression == "0 0 * * *"
        assert obj.timezone == "UTC"
        assert obj.is_active is True
        assert obj.execution_mode == "full"


class TestTranslationJobDictionary:
    """TranslationJobDictionary — many-to-many association."""

    def test_table_name(self):
        from src.models.translate import TranslationJobDictionary

        assert TranslationJobDictionary.__tablename__ == "translation_job_dictionaries"

    def test_minimal(self):
        from src.models.translate import TranslationJobDictionary

        obj = TranslationJobDictionary(id="tjd-1", job_id="j-1", dictionary_id="d-1")
        assert obj.id == "tjd-1"
        assert obj.job_id == "j-1"
        assert obj.dictionary_id == "d-1"


class TestMetricSnapshot:
    """MetricSnapshot — translation performance metrics."""

    def test_table_name(self):
        from src.models.translate import MetricSnapshot

        assert MetricSnapshot.__tablename__ == "translation_metric_snapshots"

    def test_minimal(self):
        from src.models.translate import MetricSnapshot

        obj = MetricSnapshot(id="ms-1", key_hash="hash1")
        assert obj.id == "ms-1"
        assert obj.key_hash == "hash1"


class TestTranslationLanguage:
    """TranslationLanguage — per-language result."""

    def test_table_name(self):
        from src.models.translate import TranslationLanguage

        assert TranslationLanguage.__tablename__ == "translation_languages"

    def test_minimal(self):
        from src.models.translate import TranslationLanguage

        obj = TranslationLanguage(
            id="tl-1", record_id="rec-1", language_code="ru",
            status="pending", needs_review=False, language_overridden=False,
        )
        assert obj.id == "tl-1"
        assert obj.language_code == "ru"
        assert obj.status == "pending"
        assert obj.needs_review is False
        assert obj.language_overridden is False

    def test_relationships(self):
        from src.models.translate import TranslationLanguage

        assert hasattr(TranslationLanguage, "record")


class TestTranslationPreviewLanguage:
    """TranslationPreviewLanguage — per-language preview entry."""

    def test_table_name(self):
        from src.models.translate import TranslationPreviewLanguage

        assert TranslationPreviewLanguage.__tablename__ == "translation_preview_languages"

    def test_minimal(self):
        from src.models.translate import TranslationPreviewLanguage

        obj = TranslationPreviewLanguage(
            id="tpl-1", preview_record_id="pr-1", language_code="en",
            status="pending",
        )
        assert obj.id == "tpl-1"
        assert obj.language_code == "en"
        assert obj.status == "pending"

    def test_relationships(self):
        from src.models.translate import TranslationPreviewLanguage

        assert hasattr(TranslationPreviewLanguage, "preview_record")


class TestTranslationRunLanguageStats:
    """TranslationRunLanguageStats — per-language run stats."""

    def test_table_name(self):
        from src.models.translate import TranslationRunLanguageStats

        assert TranslationRunLanguageStats.__tablename__ == "translation_run_language_stats"

    def test_minimal(self):
        from src.models.translate import TranslationRunLanguageStats

        obj = TranslationRunLanguageStats(
            id="trls-1", run_id="run-1", language_code="ru",
            total_rows=0, translated_rows=0, token_count=0, estimated_cost=0.0,
        )
        assert obj.id == "trls-1"
        assert obj.language_code == "ru"
        assert obj.total_rows == 0
        assert obj.estimated_cost == 0.0

    def test_relationships(self):
        from src.models.translate import TranslationRunLanguageStats

        assert hasattr(TranslationRunLanguageStats, "run")
# #endregion Test.Models.Translate
