"""Tool for confirming USDC payment for a discount code."""

import json
from typing import Any, Optional, Type

from langchain_core.callbacks import CallbackManagerForToolRun
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field

from langchain_insumer.wrapper import InsumerAPIWrapper


class ConfirmPaymentSchema(BaseModel):
    """Input for InsumerConfirmPaymentTool."""

    code: str = Field(
        description="Verification code from insumer_verify (e.g. INSR-A7K3M).",
    )
    tx_hash: str = Field(description="On-chain transaction hash or Solana signature.")
    chain_id: Any = Field(
        description=(
            "Chain where USDC was sent: 1 (Ethereum), 8453 (Base), "
            '137 (Polygon), 42161 (Arbitrum), 10 (Optimism), 56 (BNB), '
            '43114 (Avalanche), or "solana".'
        ),
    )
    amount: Any = Field(description="USDC amount sent.")


class InsumerConfirmPaymentTool(BaseTool):
    """Confirm USDC payment for a discount code.

    After generating a discount code with ``insumer_verify``, confirm the
    customer's USDC payment. The server verifies the on-chain transaction
    receipt and marks the code as paid.
    """

    name: str = "insumer_confirm_payment"
    description: str = (
        "Confirm USDC payment for a discount code generated by insumer_verify. "
        "Submit the verification code, USDC transaction hash, chain, and amount. "
        "Server verifies the on-chain transaction receipt."
    )
    args_schema: Type[ConfirmPaymentSchema] = ConfirmPaymentSchema

    api_wrapper: InsumerAPIWrapper = Field(..., exclude=True)

    def __init__(self, api_wrapper: InsumerAPIWrapper) -> None:
        super().__init__(api_wrapper=api_wrapper)

    def _run(
        self,
        code: str,
        tx_hash: str,
        chain_id: Any,
        amount: Any,
        run_manager: Optional[CallbackManagerForToolRun] = None,
    ) -> str:
        """Confirm payment."""
        result = self.api_wrapper.confirm_payment(
            code=code,
            tx_hash=tx_hash,
            chain_id=chain_id,
            amount=amount,
        )
        return json.dumps(result, indent=2)
