from __future__ import annotations

import json
import uuid
from dataclasses import dataclass
from sqlite3 import Connection

from jarvis_finance.audit.log import record_audit_event
from jarvis_finance.imports.common import utc_now


@dataclass(frozen=True)
class ExecutionImportResult:
    transaction_id: str
    imported: bool


def execute_initial_snapshot_plan(conn: Connection, *, execution_plan_id: str, note: str, created_by: str = "system") -> ExecutionImportResult:
    if not note.strip():
        raise ValueError("execution import requires a note")
    plan = conn.execute("SELECT * FROM broker_import_execution_plans WHERE execution_plan_id=?", (execution_plan_id,)).fetchone()
    if plan is None:
        raise ValueError(f"execution plan not found: {execution_plan_id}")
    if plan["payload_status"] != "ready":
        raise ValueError(f"execution plan is not ready: {execution_plan_id}")
    if plan["execution_status"] == "imported" or plan["transaction_id"]:
        raise ValueError(f"execution plan already imported: {execution_plan_id}")
    existing = conn.execute(
        """
        SELECT transaction_id FROM transactions
        WHERE source_type='broker_import_reviewed_snapshot'
          AND (source_id=? OR external_transaction_id=? OR row_hash=?)
        LIMIT 1
        """,
        (plan["execution_plan_id"], plan["execution_plan_id"], plan["source_row_hash"]),
    ).fetchone()
    if existing:
        raise ValueError("execution plan or source row hash already imported")
    payload = json.loads(plan["planned_write_summary_json"] or "{}")
    required = ["account_id", "instrument_id", "trade_date", "quantity", "currency_original"]
    missing = [key for key in required if not payload.get(key)]
    if missing:
        raise ValueError("execution payload missing required fields: " + ", ".join(missing))
    tx_id = "tx-" + str(uuid.uuid4())
    now = utc_now()
    quality = "warning" if (payload.get("fx_status") == "missing" or "cost_basis_uncertain" in (plan["payload_quality_flags_json"] or "")) else "ok"
    conn.execute(
        """
        INSERT INTO transactions(
          transaction_id, transaction_type, account_id, instrument_id, trade_date, settlement_date,
          quantity, price_original, gross_amount_original, fee_original, tax_original, net_amount_original,
          currency_original, fx_rate_to_chf, fx_source, fx_status, gross_amount_chf, fee_chf, tax_chf, net_amount_chf,
          source_type, source_id, external_transaction_id, row_hash, is_confirmed, quality_status, notes, created_at, updated_at
        ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
        """,
        (
            tx_id, "initial_position_snapshot", payload["account_id"], payload["instrument_id"], payload["trade_date"], payload["trade_date"],
            payload["quantity"], payload.get("price_original"), None, None, None, None,
            payload.get("currency_original"), payload.get("fx_rate_to_chf"), payload.get("fx_source") or "missing_in_source", payload.get("fx_status", "missing"), payload.get("gross_amount_chf"), None, None, None,
            "broker_import_reviewed_snapshot", plan["execution_plan_id"], plan["execution_plan_id"], plan["source_row_hash"], 1, quality,
            note, now, now,
        ),
    )
    conn.execute(
        "UPDATE broker_import_execution_plans SET execution_status='imported', transaction_id=?, executed_at=?, updated_at=?, notes=? WHERE execution_plan_id=?",
        (tx_id, now, now, note, execution_plan_id),
    )
    conn.execute(
        "UPDATE broker_import_review_items SET review_status='imported', reviewer_note=?, updated_at=? WHERE review_item_id=?",
        (note, now, plan["review_item_id"]),
    )
    record_audit_event(
        conn,
        source="broker_import_execution_plan",
        action="execute_mini_import",
        entity_type="transaction",
        entity_id=tx_id,
        old_values={},
        new_values={"execution_plan_id": execution_plan_id, "review_item_id": plan["review_item_id"], "transaction_type": "initial_position_snapshot", "quality_status": quality},
        user_text_note=note,
        confirmed=True,
        created_by=created_by,
    )
    record_audit_event(
        conn,
        source="manual_review_queue",
        action="mark_review_item_imported",
        entity_type="broker_import_review_item",
        entity_id=plan["review_item_id"],
        old_values={"review_status": "resolved"},
        new_values={"review_status": "imported", "transaction_id": tx_id},
        user_text_note=note,
        confirmed=True,
        created_by=created_by,
    )
    conn.commit()
    return ExecutionImportResult(transaction_id=tx_id, imported=True)
