# #region TestDictionaryCorrection [C:3] [TYPE Module] [SEMANTICS test, dictionary, correction, context]
# @BRIEF Validate InlineCorrectionService and dictionary correction flows.
# @RELATION BINDS_TO -> [InlineCorrectionService]

import pytest

from sqlalchemy import create_engine, event
from sqlalchemy.orm import Session, sessionmaker

from src.models.translate import (
    Base,
    DictionaryEntry,
    TranslationBatch,
    TranslationJob,
    TranslationLanguage,
    TranslationRecord,
    TranslationRun,
)
from src.plugins.translate.dictionary import DictionaryManager
from src.plugins.translate.service import InlineCorrectionService


# region db_session [TYPE Fixture]
@pytest.fixture
def db_session():
    engine = create_engine("sqlite:///:memory:", echo=False)
    @event.listens_for(engine, "connect")
    def _set_sqlite_pragma(dbapi_connection, connection_record):
        cursor = dbapi_connection.cursor()
        cursor.execute("PRAGMA foreign_keys=ON")
        cursor.close()
    Base.metadata.create_all(bind=engine)
    session = sessionmaker(bind=engine)()
    try:
        yield session
    finally:
        session.close()
        Base.metadata.drop_all(bind=engine)
# endregion db_session


class TestContextCapture:
    """Verify context auto-capture when submitting corrections."""

    # region test_context_capture_in_correction [C:2] [TYPE Function]
    def test_context_capture_in_correction(self, db_session: Session):
        d = DictionaryManager.create_dictionary(db_session, name="Test Dict", source_dialect="a", target_dialect="b")
        job = TranslationJob(name="Ctx Job", source_dialect="a", target_dialect="b", status="DRAFT")
        db_session.add(job)
        db_session.flush()

        run = TranslationRun(job_id=job.id, status="COMPLETED")
        db_session.add(run)
        db_session.flush()

        batch = TranslationBatch(run_id=run.id, batch_index=0, status="COMPLETED")
        db_session.add(batch)
        db_session.flush()

        record = TranslationRecord(
            batch_id=batch.id, run_id=run.id, source_sql="hello world",
            source_object_type="table_row", source_object_name="Row 0",
            source_object_id="0", source_data={"schema": "public", "table": "users", "column": "name"},
            status="SUCCESS",
        )
        db_session.add(record)
        db_session.flush()

        for lang_code in ("ru", "de", "fr", "it"):
            tl = TranslationLanguage(
                record_id=record.id, language_code=lang_code,
                source_language_detected="en", translated_value="translated",
                final_value="translated", status="translated",
            )
            db_session.add(tl)
        db_session.commit()

        result = InlineCorrectionService.submit_correction_to_dict(
            db=db_session, record_id=record.id, language_code="ru",
            dictionary_id=d.id, corrected_value="привет мир (исправлено)",
            current_user="test_user",
        )
        assert result["action"] == "created"
        assert result["entry_id"] is not None

        entry = db_session.query(DictionaryEntry).filter(DictionaryEntry.id == result["entry_id"]).first()
        assert entry is not None
        assert entry.has_context is True
        assert entry.context_source == "auto"
        assert entry.context_data is not None
        assert "source_data" in entry.context_data
        assert entry.context_data["source_object_type"] == "table_row"

        result2 = InlineCorrectionService.submit_correction_to_dict(
            db=db_session, record_id=record.id, language_code="de",
            dictionary_id=d.id, corrected_value="another correction",
            current_user="test_user", context_data_override={"custom_key": "custom_value"},
        )
        assert result2["action"] == "created"
        entry2 = db_session.query(DictionaryEntry).filter(DictionaryEntry.id == result2["entry_id"]).first()
        assert entry2.context_data == {"custom_key": "custom_value"}
        assert entry2.context_source == "manual"

        result3 = InlineCorrectionService.submit_correction_to_dict(
            db=db_session, record_id=record.id, language_code="fr",
            dictionary_id=d.id, corrected_value="no context",
            current_user="test_user", keep_context=False,
        )
        assert result3["action"] == "created"
        entry3 = db_session.query(DictionaryEntry).filter(DictionaryEntry.id == result3["entry_id"]).first()
        assert entry3.context_data is None
        assert entry3.has_context is False
        assert entry3.context_source == "manual"

        result4 = InlineCorrectionService.submit_correction_to_dict(
            db=db_session, record_id=record.id, language_code="it",
            dictionary_id=d.id, corrected_value="with notes",
            current_user="test_user", usage_notes="Use this for user-facing columns only",
        )
        assert result4["action"] == "created"
        entry4 = db_session.query(DictionaryEntry).filter(DictionaryEntry.id == result4["entry_id"]).first()
        assert entry4.usage_notes == "Use this for user-facing columns only"
    # endregion test_context_capture_in_correction
# #endregion TestDictionaryCorrection
