"""Local Langflow component: prepare or inspect; never approve or dispatch."""
from uuid import UUID

import httpx
from lfx.custom.custom_component.component import Component
from lfx.io import DataInput, DropdownInput, Output, SecretStrInput, StrInput
from lfx.schema.data import Data


class PraesidiaCheckpointComponent(Component):
    display_name = "Praesidia Checkpoint"
    description = "Prepare a registered HTTP request for human review or read your existing checkpoint."
    name = "PraesidiaCheckpoint"
    icon = "ShieldCheck"
    # An API origin is operator configuration, not an agent-controlled URL input.
    API_ORIGIN = "https://api.praesidia.ai"
    inputs = [
        DropdownInput(name="operation", display_name="Operation", options=["prepare", "checkpoint"], value="prepare"),
        StrInput(name="organization_id", display_name="Organization UUID", required=True),
        SecretStrInput(name="caller_credential", display_name="Personal caller credential", required=True),
        StrInput(name="target_id", display_name="Registered target ID"),
        DataInput(name="request_body", display_name="Exact request body"),
        StrInput(name="thread_id", display_name="Stable workflow run ID"),
        StrInput(name="approval_id", display_name="Existing approval UUID"),
    ]
    outputs = [Output(name="checkpoint", display_name="Checkpoint", method="read_or_prepare", cache=False)]

    async def read_or_prepare(self) -> Data:
        organization_id = str(UUID(str(self.organization_id)))
        credential = self.caller_credential
        if hasattr(credential, "get_secret_value"):
            credential = credential.get_secret_value()
        if not isinstance(credential, str) or not credential.strip():
            raise ValueError("Configure a personal caller credential in Langflow's secret input.")
        base = f"{self.API_ORIGIN}/organizations/{organization_id}/protected-actions/http"
        if self.operation == "checkpoint":
            method = "GET"
            url = f"{base}/checkpoints/{UUID(str(self.approval_id))}"
            body = None
        elif self.operation == "prepare":
            target = str(self.target_id or "").strip()
            thread = str(self.thread_id or "").strip()
            supplied = self.request_body
            request_body = supplied.data if isinstance(supplied, Data) else supplied
            if not target or len(target) > 128 or not thread or len(thread) > 256:
                raise ValueError("Set the registered target and a unique stable workflow run ID.")
            if not isinstance(request_body, dict):
                raise ValueError("The request body must be a JSON object.")
            method, url = "POST", f"{base}/prepare"
            body = {"targetId": target, "body": request_body,
                    "checkpoint": {"runtime": "custom", "threadId": thread, "nodeId": "langflow-checkpoint"},
                    "description": "Langflow registered HTTP request for separate human review"}
        else:
            raise ValueError("Only prepare and checkpoint reads are supported; this component never resumes a request.")
        try:
            async with httpx.AsyncClient(timeout=30, follow_redirects=False) as client:
                response = await client.request(method, url, headers={"Authorization": f"Bearer {credential}"}, json=body)
        except httpx.RequestError as error:
            raise ValueError("Praesidia could not be reached. Inspect the existing checkpoint before retrying.") from error
        if not 200 <= response.status_code < 300:
            raise ValueError(f"Praesidia returned HTTP {response.status_code}; no approval or dispatch is inferred.")
        payload = response.json()
        if not isinstance(payload, dict):
            raise ValueError("Unexpected checkpoint response.")
        self.status = "Checkpoint response received; inspect its actual status and evidence."
        return Data(data=payload)
