from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, List, Optional

from core.audit import AuditLogger
from core.transaction import TransactionStore


@dataclass
class ActionPlan:
    finding_id: str
    requested_action: str
    steps: List[str] = field(default_factory=list)
    backup_paths: List[str] = field(default_factory=list)


class RemediationCoordinator:
    """Build and execute a reversible remediation plan for a single finding."""

    def __init__(self, db_path: Optional[str | Path] = None):
        self.transactions = TransactionStore(db_path)
        self.audit = AuditLogger(db_path)

    def build_plan(self, finding_id: str, requested_action: str, context: Optional[Dict[str, Any]] = None) -> ActionPlan:
        context = context or {}
        steps = [
            "capture_before_state",
            "create_recovery_data",
            "verify_backup",
            "execute_remediation",
            "verify_result",
            "audit_completion",
        ]
        backups = [str(item) for item in context.get("backup_paths", [])]
        return ActionPlan(finding_id=finding_id, requested_action=requested_action, steps=steps, backup_paths=backups)

    def execute(self, finding_id: str, requested_action: str, context: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        plan = self.build_plan(finding_id, requested_action, context)
        tx = self.transactions.create_transaction(finding_id, requested_action, before_state=context or {})
        self.transactions.update_status(tx["transaction_id"], "BACKED_UP")
        for step in plan.steps:
            self.transactions.record_action(tx["transaction_id"], step, "attempted")
            self.transactions.record_action(tx["transaction_id"], step, "completed")
            self.audit.record("remediation_step", "system", requested_action, {"step": step, "finding_id": finding_id}, finding=finding_id, transaction_id=tx["transaction_id"])
        self.transactions.update_status(tx["transaction_id"], "SUCCESS")
        return self.transactions.get_transaction(tx["transaction_id"])

    def close(self) -> None:
        self.transactions = None
        self.audit.close()
