# #region TranslateRunEditRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, edit, correction, bulk, override]
# @defgroup Api Module group.
# @BRIEF Translation Run inline edit, bulk find-replace, and language override routes.
# @LAYER API
# @RELATION DEPENDS_ON -> [TranslateRunRoutesModule]
# @RELATION CALLED_BY -> [TranslateRoutes]

from fastapi import Depends, HTTPException, status
from sqlalchemy.orm import Session

from ....core.config_manager import ConfigManager
from ....core.database import get_db
from ....core.logger import logger
from ....dependencies import get_config_manager, get_current_user, has_permission
from ....schemas.auth import User
from ....schemas.translate import (
    BulkFindReplaceRequest,
    InlineEditRequest,
    OverrideLanguageRequest,
)
from ._router import router


# #region override_detected_language [C:4] [TYPE Function]
# @ingroup Api
# @BRIEF Manually override the detected source language for a specific translation language entry.
# @PRE  User has translate.job.execute permission. Run, record, and language entry exist.
# @POST  TranslationLanguage.source_language_detected is updated; language_overridden is set to True.
# @SIDE_EFFECT  DB write.
@router.put("/runs/{run_id}/records/{record_id}/languages/{language_code}/override-language")
def override_detected_language(
    run_id: str,
    record_id: str,
    language_code: str,
    payload: OverrideLanguageRequest,
    current_user: User = Depends(get_current_user),
    _ = Depends(has_permission("translate.job", "EXECUTE")),
    db: Session = Depends(get_db),
):
    logger.reason(
        f"override_detected_language — Run: {run_id}, Record: {record_id}, "
        f"Lang: {language_code}, Override: {payload.source_language}",
        extra={"src": "translate_routes"},
    )
    try:
        from ....models.translate import TranslationLanguage, TranslationRecord

        record = (
            db.query(TranslationRecord)
            .filter(
                TranslationRecord.id == record_id,
                TranslationRecord.run_id == run_id,
            )
            .first()
        )
        if not record:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Translation record '{record_id}' not found in run '{run_id}'",
            )

        lang_entry = (
            db.query(TranslationLanguage)
            .filter(
                TranslationLanguage.record_id == record_id,
                TranslationLanguage.language_code == language_code,
            )
            .first()
        )
        if not lang_entry:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Language entry '{language_code}' not found for record '{record_id}'",
            )

        lang_entry.source_language_detected = payload.source_language
        lang_entry.language_overridden = True
        lang_entry.needs_review = False
        db.commit()
        db.refresh(lang_entry)

        logger.reason("Language override applied", {
            "run_id": run_id,
            "record_id": record_id,
            "language_code": language_code,
            "new_source_language": payload.source_language,
            "overridden_by": current_user.username,
        })

        from ....schemas.translate import TranslationLanguageResponse
        return TranslationLanguageResponse.model_validate(lang_entry)
    except HTTPException:
        raise
    except Exception as e:
        logger.explore("override_detected_language failed", extra={"src": "translate_routes", "error": str(e)})
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
# #endregion override_detected_language


# #region inline_edit_translation [C:4] [TYPE Function] [SEMANTICS api,translate,correction]
# @ingroup Api
# @BRIEF Apply an inline correction to a translated value on a completed run result.
# @PRE  User has translate.job.execute permission. Run, record, and language entry exist.
# @POST  TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.
@router.put("/runs/{run_id}/records/{record_id}/languages/{language_code}")
def inline_edit_translation(
    run_id: str,
    record_id: str,
    language_code: str,
    payload: InlineEditRequest,
    current_user: User = Depends(get_current_user),
    _ = Depends(has_permission("translate.job", "EXECUTE")),
    db: Session = Depends(get_db),
):
    logger.reason(
        f"inline_edit_translation — Run: {run_id}, Record: {record_id}, "
        f"Lang: {language_code}, User: {current_user.username}",
        extra={"src": "translate_routes"},
    )
    try:
        from ....plugins.translate.service import InlineCorrectionService

        result = InlineCorrectionService.apply_inline_edit(
            db=db,
            run_id=run_id,
            record_id=record_id,
            language_code=language_code,
            final_value=payload.final_value,
            submit_to_dictionary=payload.submit_to_dictionary,
            dictionary_id=payload.dictionary_id,
            current_user=current_user.username,
            context_data_override=payload.context_data_override,
            usage_notes=payload.usage_notes,
            keep_context=payload.keep_context,
        )
        return result
    except ValueError as e:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
    except Exception as e:
        logger.explore("inline_edit_translation failed", extra={"src": "translate_routes", "error": str(e)})
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
# #endregion inline_edit_translation


# #region bulk_find_replace [C:4] [TYPE Function] [SEMANTICS api,translate,bulk,replace]
# @ingroup Api
# @BRIEF Perform bulk find-and-replace on translated values within a run.
# @PRE User has translate.job.execute permission. Run exists.
# @POST If preview=false, matching translations are updated. Optional dictionary submission.
@router.post("/runs/{run_id}/bulk-replace")
def bulk_find_replace(
    run_id: str,
    payload: BulkFindReplaceRequest,
    current_user: User = Depends(get_current_user),
    _ = Depends(has_permission("translate.job", "EXECUTE")),
    db: Session = Depends(get_db),
):
    logger.reason(
        f"bulk_find_replace — Run: {run_id}, Pattern: '{payload.find_pattern}', "
        f"Regex: {payload.is_regex}, Lang: {payload.target_language}, "
        f"User: {current_user.username}",
        extra={"src": "translate_routes"},
    )
    try:
        from ....plugins.translate.service import BulkFindReplaceService

        if payload.preview:
            preview = BulkFindReplaceService.preview(
                db=db,
                run_id=run_id,
                pattern=payload.find_pattern,
                is_regex=payload.is_regex,
                replacement_text=payload.replacement_text,
                target_language=payload.target_language,
            )
            return {
                "rows_affected": len(preview),
                "corrections_submitted": 0,
                "preview": preview,
            }

        result = BulkFindReplaceService.apply(
            db=db,
            run_id=run_id,
            pattern=payload.find_pattern,
            is_regex=payload.is_regex,
            replacement_text=payload.replacement_text,
            target_language=payload.target_language,
            submit_to_dictionary=payload.submit_to_dictionary,
            dictionary_id=payload.dictionary_id,
            usage_notes=payload.usage_notes,
            current_user=current_user.username,
            submit_to_dictionary_with_context=payload.submit_to_dictionary_with_context,
        )
        return result
    except ValueError as e:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
    except Exception as e:
        logger.explore("bulk_find_replace failed", extra={"src": "translate_routes", "error": str(e)})
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
# #endregion bulk_find_replace


# #endregion TranslateRunEditRoutesModule
