from __future__ import annotations

import uuid
from sqlite3 import Connection

from jarvis_finance.audit.log import record_audit_event
from jarvis_finance.imports.common import utc_now
from jarvis_finance.quality.alerts import create_alert


def void_transaction(conn: Connection, *, transaction_id: str, note: str, created_by: str = "system") -> str:
    """Mark a productive transaction as voided without deleting it.

    The original row remains in the ledger for auditability. Position and cash
    calculations ignore rows with ``is_voided=1``.
    """
    if not note.strip():
        raise ValueError("void_transaction requires a note")
    row = conn.execute("SELECT * FROM transactions WHERE transaction_id=?", (transaction_id,)).fetchone()
    if row is None:
        raise ValueError(f"transaction not found: {transaction_id}")
    if int(row["is_voided"] or 0) == 1:
        raise ValueError(f"transaction is already voided: {transaction_id}")
    now = utc_now()
    conn.execute(
        """
        UPDATE transactions
        SET is_voided=1, voided_at=?, void_reason=?, voided_by=?, updated_at=?
        WHERE transaction_id=?
        """,
        (now, note, created_by, now, transaction_id),
    )
    audit_id = record_audit_event(
        conn,
        source="ledger_corrections",
        action="void_transaction",
        entity_type="transaction",
        entity_id=transaction_id,
        old_values={"is_voided": int(row["is_voided"] or 0), "quality_status": row["quality_status"]},
        new_values={"is_voided": 1, "voided_at": now, "void_reason": note},
        user_text_note=note,
        confirmed=True,
        created_by=created_by,
    )
    create_alert(
        conn,
        priority="warnung",
        category="ledger",
        entity_type="transaction",
        entity_id=transaction_id,
        rule_id="voided_transaction",
        message="A ledger transaction was voided and remains excluded from active position/cash calculations.",
        evidence={"transaction_id": transaction_id, "voided_at": now},
    )
    conn.commit()
    return audit_id


def record_correction_audit(
    conn: Connection,
    *,
    old_transaction_id: str,
    new_transaction_id: str,
    note: str,
    created_by: str = "system",
) -> str:
    """Link an existing transaction to its correction transaction via audit.

    Creation of the replacement transaction remains with the caller/importer so
    quantities and source-specific fields stay under that workflow's validation.
    """
    if not note.strip():
        raise ValueError("correction transaction requires a note")
    old_row = conn.execute("SELECT transaction_id FROM transactions WHERE transaction_id=?", (old_transaction_id,)).fetchone()
    new_row = conn.execute("SELECT transaction_id FROM transactions WHERE transaction_id=?", (new_transaction_id,)).fetchone()
    if old_row is None or new_row is None:
        raise ValueError("old and new transactions must both exist")
    now = utc_now()
    conn.execute(
        """
        UPDATE transactions
        SET correction_of_transaction_id=?, correction_reason=?, updated_at=?
        WHERE transaction_id=?
        """,
        (old_transaction_id, note, now, new_transaction_id),
    )
    audit_id = record_audit_event(
        conn,
        source="ledger_corrections",
        action="correction_transaction",
        entity_type="transaction",
        entity_id=new_transaction_id,
        old_values={"old_transaction_id": old_transaction_id},
        new_values={"new_transaction_id": new_transaction_id, "correction_of_transaction_id": old_transaction_id},
        user_text_note=note,
        confirmed=True,
        created_by=created_by,
    )
    conn.commit()
    return audit_id
